pjs/layout/style/nsStyleContext.cpp

3726 строки
115 KiB
C++
Исходник Обычный вид История

1998-04-14 00:24:54 +04:00
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
1998-04-14 00:24:54 +04:00
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
1998-04-14 00:24:54 +04:00
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
1998-04-14 00:24:54 +04:00
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
* IBM Corporation
*
* This Original Code has been modified by IBM Corporation.
* Modifications made by IBM described herein are
* Copyright (c) International Business Machines
* Corporation, 2000
*
* Modifications to Mozilla code or documentation
* identified per MPL Section 3.3
*
* Date Modified by Description of modification
* 03/20/2000 IBM Corp. BiDi - ability to change the default direction of the browser
*
1998-04-14 00:24:54 +04:00
*/
#include "nsIStyleContext.h"
#include "nsIMutableStyleContext.h"
1998-04-14 00:24:54 +04:00
#include "nsStyleConsts.h"
#include "nsString.h"
#include "nsUnitConversion.h"
#include "nsIPresContext.h"
#include "nsIStyleRule.h"
#include "nsISupportsArray.h"
#include "nsCRT.h"
#include "nsIFrame.h"
#include "nsCOMPtr.h"
#include "nsIStyleSet.h"
#include "nsISizeOfHandler.h"
#include "nsIPresShell.h"
#include "nsLayoutAtoms.h"
#include "prenv.h"
1998-04-14 00:24:54 +04:00
static NS_DEFINE_IID(kIStyleContextIID, NS_ISTYLECONTEXT_IID);
1999-04-02 22:48:55 +04:00
#define DELETE_ARRAY_IF(array) if (array) { delete[] array; array = nsnull; }
1998-04-21 04:02:44 +04:00
#ifdef DEBUG
// #define NOISY_DEBUG
#endif
// --------------------------------------
// Macros for getting style data structs
// - if using external data, get from
// the member style data instance
// - if internal, get the data member
#ifdef SHARE_STYLECONTEXTS
#define GETSCDATA(data) mStyleData->m##data
#else
#define GETSCDATA(data) m##data
#endif
#ifdef SHARE_STYLECONTEXTS
// define COMPUTE_STYLEDATA_CRC to actually compute a valid CRC32
// - if not defined then the CRC will simply be 0 (see StyleContextData::ComputeCRC)
// - this is to avoid the cost of computing a CRC if it is not being used
// by the style set in caching the style contexts (not using the FAST_CACHE)
// which is the current situation since the CRC can change when GetMutableStyleData
// is used to poke values into the style context data.
// #define COMPUTE_STYLEDATA_CRC
#endif //SHARE_STYLECONTEXTS
#ifdef COMPUTE_STYLEDATA_CRC
// helpers for computing CRC32 on style data
static void gen_crc_table();
static PRUint32 AccumulateCRC(PRUint32 crc_accum, const char *data_blk_ptr, int data_blk_size);
static PRUint32 StyleSideCRC(PRUint32 crc,const nsStyleSides *aStyleSides);
static PRUint32 StyleCoordCRC(PRUint32 crc, const nsStyleCoord* aCoord);
static PRUint32 StyleMarginCRC(PRUint32 crc, const nsMargin *aMargin);
static PRUint32 StyleStringCRC(PRUint32 aCrc, const nsString *aString);
#endif // COMPUTE_STYLEDATA_CRC
inline PRBool IsFixedUnit(nsStyleUnit aUnit, PRBool aEnumOK)
{
return PRBool((aUnit == eStyleUnit_Null) ||
(aUnit == eStyleUnit_Coord) ||
(aEnumOK && (aUnit == eStyleUnit_Enumerated)));
}
static PRBool IsFixedData(const nsStyleSides& aSides, PRBool aEnumOK);
static nscoord CalcCoord(const nsStyleCoord& aCoord,
const nscoord* aEnumTable,
PRInt32 aNumEnums);
// EnsureBlockDisplay:
// - if the display value (argument) is not a block-type
// then we set it to a valid block display value
// - For enforcing the floated/positioned element CSS2 rules
static void EnsureBlockDisplay(/*in out*/PRUint8 &display);
1998-04-21 04:02:44 +04:00
// --------------------
// nsStyleFont
//
nsStyleFont::nsStyleFont(void)
: mFont(nsnull, NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL, NS_FONT_DECORATION_NONE, 0),
mFixedFont(nsnull, NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL, NS_FONT_DECORATION_NONE, 0)
{}
nsStyleFont::nsStyleFont(const nsFont& aVariableFont, const nsFont& aFixedFont)
: mFont(aVariableFont),
mFixedFont(aFixedFont)
{ }
1998-04-14 00:24:54 +04:00
nsStyleFont::~nsStyleFont(void) { }
1998-04-14 00:24:54 +04:00
1998-04-14 00:24:54 +04:00
struct StyleFontImpl : public nsStyleFont {
StyleFontImpl(const nsFont& aVariableFont, const nsFont& aFixedFont)
: nsStyleFont(aVariableFont, aFixedFont)
1998-04-14 00:24:54 +04:00
{}
void ResetFrom(const nsStyleFont* aParent, nsIPresContext* aPresContext);
void SetFrom(const nsStyleFont& aSource);
void CopyTo(nsStyleFont& aDest) const;
1999-02-27 10:11:42 +03:00
PRInt32 CalcDifference(const StyleFontImpl& aOther) const;
static PRInt32 CalcFontDifference(const nsFont& aFont1, const nsFont& aFont2);
PRUint32 ComputeCRC32(PRUint32 crc) const;
1998-04-14 00:24:54 +04:00
private: // These are not allowed
StyleFontImpl(const StyleFontImpl& aOther);
StyleFontImpl& operator=(const StyleFontImpl& aOther);
};
void StyleFontImpl::ResetFrom(const nsStyleFont* aParent, nsIPresContext* aPresContext)
1998-04-14 00:24:54 +04:00
{
if (nsnull != aParent) {
mFont = aParent->mFont;
mFixedFont = aParent->mFixedFont;
1998-07-23 21:57:16 +04:00
mFlags = aParent->mFlags;
}
else {
aPresContext->GetDefaultFont(mFont);
aPresContext->GetDefaultFixedFont(mFixedFont);
1998-07-23 21:57:16 +04:00
mFlags = NS_STYLE_FONT_DEFAULT;
}
1998-04-14 00:24:54 +04:00
}
void StyleFontImpl::SetFrom(const nsStyleFont& aSource)
{
mFont = aSource.mFont;
mFixedFont = aSource.mFixedFont;
mFlags = aSource.mFlags;
}
void StyleFontImpl::CopyTo(nsStyleFont& aDest) const
{
aDest.mFont = mFont;
aDest.mFixedFont = mFixedFont;
aDest.mFlags = mFlags;
}
1999-02-27 10:11:42 +03:00
PRInt32 StyleFontImpl::CalcDifference(const StyleFontImpl& aOther) const
{
if (mFlags == aOther.mFlags) {
PRInt32 impact = CalcFontDifference(mFont, aOther.mFont);
if (impact < NS_STYLE_HINT_REFLOW) {
impact = CalcFontDifference(mFixedFont, aOther.mFixedFont);
}
return impact;
}
return NS_STYLE_HINT_REFLOW;
}
PRInt32 StyleFontImpl::CalcFontDifference(const nsFont& aFont1, const nsFont& aFont2)
{
if ((aFont1.size == aFont2.size) &&
(aFont1.style == aFont2.style) &&
(aFont1.variant == aFont2.variant) &&
(aFont1.weight == aFont2.weight) &&
(aFont1.name == aFont2.name)) {
if ((aFont1.decorations == aFont2.decorations)) {
return NS_STYLE_HINT_NONE;
}
return NS_STYLE_HINT_VISUAL;
1999-02-27 10:11:42 +03:00
}
return NS_STYLE_HINT_REFLOW;
}
PRUint32 StyleFontImpl::ComputeCRC32(PRUint32 aCrc) const
{
PRUint32 crc = aCrc;
#ifdef COMPUTE_STYLEDATA_CRC
crc = AccumulateCRC(crc,(const char *)&(mFont.size),sizeof(mFont.size));
crc = AccumulateCRC(crc,(const char *)&(mFont.style),sizeof(mFont.style));
crc = AccumulateCRC(crc,(const char *)&(mFont.variant),sizeof(mFont.variant));
crc = AccumulateCRC(crc,(const char *)&(mFont.weight),sizeof(mFont.weight));
crc = AccumulateCRC(crc,(const char *)&(mFont.decorations),sizeof(mFont.decorations));
crc = StyleStringCRC(crc,&(mFont.name));
crc = AccumulateCRC(crc,(const char *)&(mFixedFont.size),sizeof(mFixedFont.size));
crc = AccumulateCRC(crc,(const char *)&(mFixedFont.style),sizeof(mFixedFont.style));
crc = AccumulateCRC(crc,(const char *)&(mFixedFont.variant),sizeof(mFixedFont.variant));
crc = AccumulateCRC(crc,(const char *)&(mFixedFont.weight),sizeof(mFixedFont.weight));
crc = AccumulateCRC(crc,(const char *)&(mFixedFont.decorations),sizeof(mFixedFont.decorations));
crc = StyleStringCRC(crc,&(mFixedFont.name));
crc = AccumulateCRC(crc,(const char *)&mFlags,sizeof(mFlags));
#endif
return crc;
}
1999-02-27 10:11:42 +03:00
1998-04-21 04:02:44 +04:00
// --------------------
// nsStyleColor
//
nsStyleColor::nsStyleColor(void) { }
nsStyleColor::~nsStyleColor(void) { }
1998-04-14 00:24:54 +04:00
struct StyleColorImpl: public nsStyleColor {
StyleColorImpl(void) { }
1998-04-14 00:24:54 +04:00
void ResetFrom(const nsStyleColor* aParent, nsIPresContext* aPresContext);
void SetFrom(const nsStyleColor& aSource);
void CopyTo(nsStyleColor& aDest) const;
1999-02-27 10:11:42 +03:00
PRInt32 CalcDifference(const StyleColorImpl& aOther) const;
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
1998-04-14 00:24:54 +04:00
private: // These are not allowed
StyleColorImpl(const StyleColorImpl& aOther);
StyleColorImpl& operator=(const StyleColorImpl& aOther);
};
void StyleColorImpl::ResetFrom(const nsStyleColor* aParent, nsIPresContext* aPresContext)
1998-04-14 00:24:54 +04:00
{
if (nsnull != aParent) {
mColor = aParent->mColor;
1999-03-25 09:34:57 +03:00
mOpacity = aParent->mOpacity;
mCursor = aParent->mCursor; // fix for bugzilla bug 51113
}
else {
if (nsnull != aPresContext) {
aPresContext->GetDefaultColor(&mColor);
}
else {
mColor = NS_RGB(0x00, 0x00, 0x00);
}
1999-03-25 09:34:57 +03:00
mOpacity = 1.0f;
mCursor = NS_STYLE_CURSOR_AUTO; // fix for bugzilla bug 51113
}
mBackgroundFlags = NS_STYLE_BG_COLOR_TRANSPARENT | NS_STYLE_BG_IMAGE_NONE;
if (nsnull != aPresContext) {
aPresContext->GetDefaultBackgroundColor(&mBackgroundColor);
aPresContext->GetDefaultBackgroundImageAttachment(&mBackgroundAttachment);
aPresContext->GetDefaultBackgroundImageRepeat(&mBackgroundRepeat);
aPresContext->GetDefaultBackgroundImageOffset(&mBackgroundXPosition, &mBackgroundYPosition);
aPresContext->GetDefaultBackgroundImage(mBackgroundImage);
}
else {
mBackgroundColor = NS_RGB(192,192,192);
mBackgroundAttachment = NS_STYLE_BG_ATTACHMENT_SCROLL;
mBackgroundRepeat = NS_STYLE_BG_REPEAT_XY;
mBackgroundXPosition = 0;
mBackgroundYPosition = 0;
}
1998-04-14 00:24:54 +04:00
}
void StyleColorImpl::SetFrom(const nsStyleColor& aSource)
{
mColor = aSource.mColor;
mBackgroundAttachment = aSource.mBackgroundAttachment;
mBackgroundFlags = aSource.mBackgroundFlags;
mBackgroundRepeat = aSource.mBackgroundRepeat;
mBackgroundColor = aSource.mBackgroundColor;
mBackgroundXPosition = aSource.mBackgroundXPosition;
mBackgroundYPosition = aSource.mBackgroundYPosition;
mBackgroundImage = aSource.mBackgroundImage;
mCursor = aSource.mCursor;
mCursorImage = aSource.mCursorImage;
mOpacity = aSource.mOpacity;
}
void StyleColorImpl::CopyTo(nsStyleColor& aDest) const
{
aDest.mColor = mColor;
aDest.mBackgroundAttachment = mBackgroundAttachment;
aDest.mBackgroundFlags = mBackgroundFlags;
aDest.mBackgroundRepeat = mBackgroundRepeat;
aDest.mBackgroundColor = mBackgroundColor;
aDest.mBackgroundXPosition = mBackgroundXPosition;
aDest.mBackgroundYPosition = mBackgroundYPosition;
aDest.mBackgroundImage = mBackgroundImage;
aDest.mCursor = mCursor;
aDest.mCursorImage = mCursorImage;
aDest.mOpacity = mOpacity;
}
1999-02-27 10:11:42 +03:00
PRInt32 StyleColorImpl::CalcDifference(const StyleColorImpl& aOther) const
{
if ((mColor == aOther.mColor) &&
(mBackgroundAttachment == aOther.mBackgroundAttachment) &&
(mBackgroundFlags == aOther.mBackgroundFlags) &&
(mBackgroundRepeat == aOther.mBackgroundRepeat) &&
(mBackgroundColor == aOther.mBackgroundColor) &&
(mBackgroundXPosition == aOther.mBackgroundXPosition) &&
(mBackgroundYPosition == aOther.mBackgroundYPosition) &&
(mBackgroundImage == aOther.mBackgroundImage) &&
(mCursor == aOther.mCursor) &&
(mCursorImage == aOther.mCursorImage) &&
(mOpacity == aOther.mOpacity)) {
return NS_STYLE_HINT_NONE;
}
return NS_STYLE_HINT_VISUAL;
}
1998-04-14 00:24:54 +04:00
PRUint32 StyleColorImpl::ComputeCRC32(PRUint32 aCrc) const
{
PRUint32 crc = aCrc;
#ifdef COMPUTE_STYLEDATA_CRC
crc = AccumulateCRC(crc,(const char *)&mColor,sizeof(mColor));
crc = AccumulateCRC(crc,(const char *)&mBackgroundAttachment,sizeof(mBackgroundAttachment));
crc = AccumulateCRC(crc,(const char *)&mBackgroundFlags,sizeof(mBackgroundFlags));
crc = AccumulateCRC(crc,(const char *)&mBackgroundRepeat,sizeof(mBackgroundRepeat));
crc = AccumulateCRC(crc,(const char *)&mBackgroundColor,sizeof(mBackgroundColor));
crc = AccumulateCRC(crc,(const char *)&mBackgroundXPosition,sizeof(mBackgroundXPosition));
crc = AccumulateCRC(crc,(const char *)&mBackgroundYPosition,sizeof(mBackgroundYPosition));
crc = StyleStringCRC(crc,&mBackgroundImage);
crc = AccumulateCRC(crc,(const char *)&mCursor,sizeof(mCursor));
crc = StyleStringCRC(crc,&mCursorImage);
crc = AccumulateCRC(crc,(const char *)&mOpacity,sizeof(mOpacity));
#endif
return crc;
}
1998-04-21 04:02:44 +04:00
// --------------------
// nsStyleSpacing
//
// XXX this is here to support deprecated calc spacing methods only
static nscoord kBorderWidths[3];
static PRBool kWidthsInitialized = PR_FALSE;
nsStyleSpacing::nsStyleSpacing(void) { }
#define NS_SPACING_MARGIN 0
#define NS_SPACING_PADDING 1
#define NS_SPACING_BORDER 2
static nscoord CalcSideFor(const nsIFrame* aFrame, const nsStyleCoord& aCoord,
PRUint8 aSpacing, PRUint8 aSide,
const nscoord* aEnumTable, PRInt32 aNumEnums)
{
nscoord result = 0;
switch (aCoord.GetUnit()) {
case eStyleUnit_Auto:
1999-02-18 06:24:58 +03:00
// Auto margins are handled by layout
break;
case eStyleUnit_Inherit:
nsIFrame* parentFrame;
aFrame->GetParent(&parentFrame); // XXX may not be direct parent...
if (nsnull != parentFrame) {
nsIStyleContext* parentContext;
parentFrame->GetStyleContext(&parentContext);
if (nsnull != parentContext) {
const nsStyleSpacing* parentSpacing = (const nsStyleSpacing*)parentContext->GetStyleData(eStyleStruct_Spacing);
nsMargin parentMargin;
switch (aSpacing) {
case NS_SPACING_MARGIN: parentSpacing->CalcMarginFor(parentFrame, parentMargin);
break;
case NS_SPACING_PADDING: parentSpacing->CalcPaddingFor(parentFrame, parentMargin);
break;
case NS_SPACING_BORDER: parentSpacing->CalcBorderFor(parentFrame, parentMargin);
break;
}
switch (aSide) {
case NS_SIDE_LEFT: result = parentMargin.left; break;
case NS_SIDE_TOP: result = parentMargin.top; break;
case NS_SIDE_RIGHT: result = parentMargin.right; break;
case NS_SIDE_BOTTOM: result = parentMargin.bottom; break;
}
NS_RELEASE(parentContext);
}
}
1998-10-27 06:03:02 +03:00
break;
case eStyleUnit_Percent:
{
nscoord baseWidth = 0;
PRBool isBase = PR_FALSE;
nsIFrame* frame;
aFrame->GetParent(&frame);
while (nsnull != frame) {
frame->IsPercentageBase(isBase);
if (isBase) {
nsSize size;
frame->GetSize(size);
1998-05-19 01:04:26 +04:00
baseWidth = size.width; // not really width, need to subtract out padding...
break;
}
frame->GetParent(&frame);
}
result = (nscoord)((float)baseWidth * aCoord.GetPercentValue());
}
break;
case eStyleUnit_Coord:
result = aCoord.GetCoordValue();
break;
case eStyleUnit_Enumerated:
if (nsnull != aEnumTable) {
PRInt32 value = aCoord.GetIntValue();
if ((0 <= value) && (value < aNumEnums)) {
return aEnumTable[aCoord.GetIntValue()];
}
}
break;
case eStyleUnit_Null:
case eStyleUnit_Normal:
case eStyleUnit_Integer:
case eStyleUnit_Proportional:
default:
result = 0;
break;
}
1998-09-22 06:08:45 +04:00
if ((NS_SPACING_PADDING == aSpacing) || (NS_SPACING_BORDER == aSpacing)) {
if (result < 0) {
result = 0;
}
}
return result;
}
static void CalcSidesFor(const nsIFrame* aFrame, const nsStyleSides& aSides,
PRUint8 aSpacing,
const nscoord* aEnumTable, PRInt32 aNumEnums,
nsMargin& aResult)
{
nsStyleCoord coord;
aResult.left = CalcSideFor(aFrame, aSides.GetLeft(coord), aSpacing, NS_SIDE_LEFT,
aEnumTable, aNumEnums);
aResult.top = CalcSideFor(aFrame, aSides.GetTop(coord), aSpacing, NS_SIDE_TOP,
aEnumTable, aNumEnums);
aResult.right = CalcSideFor(aFrame, aSides.GetRight(coord), aSpacing, NS_SIDE_RIGHT,
aEnumTable, aNumEnums);
aResult.bottom = CalcSideFor(aFrame, aSides.GetBottom(coord), aSpacing, NS_SIDE_BOTTOM,
aEnumTable, aNumEnums);
}
void nsStyleSpacing::CalcMarginFor(const nsIFrame* aFrame, nsMargin& aMargin) const
{
if (mHasCachedMargin) {
aMargin = mCachedMargin;
} else {
CalcSidesFor(aFrame, mMargin, NS_SPACING_MARGIN, nsnull, 0, aMargin);
}
}
void nsStyleSpacing::CalcPaddingFor(const nsIFrame* aFrame, nsMargin& aPadding) const
{
if (mHasCachedPadding) {
aPadding = mCachedPadding;
} else {
CalcSidesFor(aFrame, mPadding, NS_SPACING_PADDING, nsnull, 0, aPadding);
}
}
void nsStyleSpacing::CalcBorderFor(const nsIFrame* aFrame, nsMargin& aBorder) const
{
if (mHasCachedBorder) {
aBorder = mCachedBorder;
} else {
CalcSidesFor(aFrame, mBorder, NS_SPACING_BORDER, kBorderWidths, 3, aBorder);
}
}
void nsStyleSpacing::CalcBorderPaddingFor(const nsIFrame* aFrame, nsMargin& aBorderPadding) const
1998-04-21 04:02:44 +04:00
{
if (mHasCachedPadding && mHasCachedBorder) {
aBorderPadding = mCachedBorderPadding;
} else {
nsMargin border;
CalcBorderFor(aFrame, border);
CalcPaddingFor(aFrame, aBorderPadding);
aBorderPadding += border;
}
1998-04-21 04:02:44 +04:00
}
PRBool nsStyleSpacing::GetMargin(nsMargin& aMargin) const
{
if (mHasCachedMargin) {
aMargin = mCachedMargin;
return PR_TRUE;
}
return PR_FALSE;
}
PRBool nsStyleSpacing::GetPadding(nsMargin& aPadding) const
{
if (mHasCachedPadding) {
aPadding = mCachedPadding;
return PR_TRUE;
}
return PR_FALSE;
}
PRBool nsStyleSpacing::GetBorder(nsMargin& aBorder) const
{
if (mHasCachedBorder) {
aBorder = mCachedBorder;
return PR_TRUE;
}
return PR_FALSE;
}
PRBool nsStyleSpacing::GetBorderPadding(nsMargin& aBorderPadding) const
{
if (mHasCachedPadding && mHasCachedBorder) {
aBorderPadding = mCachedBorderPadding;
return PR_TRUE;
}
return PR_FALSE;
}
#define BORDER_COLOR_DEFINED 0x80
#define BORDER_COLOR_SPECIAL 0x40
#define BORDER_STYLE_MASK 0x3F
PRUint8 nsStyleSpacing::GetBorderStyle(PRUint8 aSide) const
{
NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
return (mBorderStyle[aSide] & BORDER_STYLE_MASK);
}
void nsStyleSpacing::SetBorderStyle(PRUint8 aSide, PRUint8 aStyle)
{
NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
mBorderStyle[aSide] &= ~BORDER_STYLE_MASK;
mBorderStyle[aSide] |= (aStyle & BORDER_STYLE_MASK);
}
PRBool nsStyleSpacing::GetBorderColor(PRUint8 aSide, nscolor& aColor) const
{
NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
if ((mBorderStyle[aSide] & BORDER_COLOR_SPECIAL) == 0) {
aColor = mBorderColor[aSide];
return PR_TRUE;
}
return PR_FALSE;
}
void nsStyleSpacing::SetBorderColor(PRUint8 aSide, nscolor aColor)
{
NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
mBorderColor[aSide] = aColor;
mBorderStyle[aSide] &= ~BORDER_COLOR_SPECIAL;
mBorderStyle[aSide] |= BORDER_COLOR_DEFINED;
}
void nsStyleSpacing::SetBorderTransparent(PRUint8 aSide)
{
NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
mBorderStyle[aSide] |= (BORDER_COLOR_DEFINED | BORDER_COLOR_SPECIAL);
}
void nsStyleSpacing::UnsetBorderColor(PRUint8 aSide)
{
NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
mBorderStyle[aSide] &= BORDER_STYLE_MASK;
}
PRBool nsStyleSpacing::GetOutlineWidth(nscoord& aWidth) const
{
if (mHasCachedOutline) {
aWidth = mCachedOutlineWidth;
return PR_TRUE;
}
return PR_FALSE;
}
PRUint8 nsStyleSpacing::GetOutlineStyle(void) const
{
return (mOutlineStyle & BORDER_STYLE_MASK);
}
void nsStyleSpacing::SetOutlineStyle(PRUint8 aStyle)
{
mOutlineStyle &= ~BORDER_STYLE_MASK;
mOutlineStyle |= (aStyle & BORDER_STYLE_MASK);
}
PRBool nsStyleSpacing::GetOutlineColor(nscolor& aColor) const
{
if ((mOutlineStyle & BORDER_COLOR_SPECIAL) == 0) {
aColor = mOutlineColor;
return PR_TRUE;
}
return PR_FALSE;
}
void nsStyleSpacing::SetOutlineColor(nscolor aColor)
{
mOutlineColor = aColor;
mOutlineStyle &= ~BORDER_COLOR_SPECIAL;
mOutlineStyle |= BORDER_COLOR_DEFINED;
}
void nsStyleSpacing::SetOutlineInvert(void)
{
mOutlineStyle |= (BORDER_COLOR_DEFINED | BORDER_COLOR_SPECIAL);
}
1998-04-21 04:02:44 +04:00
struct StyleSpacingImpl: public nsStyleSpacing {
StyleSpacingImpl(void)
: nsStyleSpacing()
{}
void ResetFrom(const nsStyleSpacing* aParent, nsIPresContext* aPresContext);
void SetFrom(const nsStyleSpacing& aSource);
void CopyTo(nsStyleSpacing& aDest) const;
PRBool IsBorderSideVisible(PRUint8 aSide) const;
void RecalcData(nsIPresContext* aPresContext, nscolor color);
1999-02-27 10:11:42 +03:00
PRInt32 CalcDifference(const StyleSpacingImpl& aOther) const;
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
1998-04-21 04:02:44 +04:00
};
void StyleSpacingImpl::ResetFrom(const nsStyleSpacing* aParent, nsIPresContext* aPresContext)
1998-04-21 04:02:44 +04:00
{
// XXX support kBorderWidhts until deprecated methods are removed
if (! kWidthsInitialized) {
float pixelsToTwips = 20.0f;
if (aPresContext) {
aPresContext->GetPixelsToTwips(&pixelsToTwips);
}
kBorderWidths[NS_STYLE_BORDER_WIDTH_THIN] = NSIntPixelsToTwips(1, pixelsToTwips);
kBorderWidths[NS_STYLE_BORDER_WIDTH_MEDIUM] = NSIntPixelsToTwips(3, pixelsToTwips);
kBorderWidths[NS_STYLE_BORDER_WIDTH_THICK] = NSIntPixelsToTwips(5, pixelsToTwips);
kWidthsInitialized = PR_TRUE;
}
1998-04-21 04:02:44 +04:00
// spacing values not inherited
mMargin.Reset();
mPadding.Reset();
nsStyleCoord medium(NS_STYLE_BORDER_WIDTH_MEDIUM, eStyleUnit_Enumerated);
mBorder.SetLeft(medium);
mBorder.SetTop(medium);
mBorder.SetRight(medium);
mBorder.SetBottom(medium);
mBorderStyle[0] = NS_STYLE_BORDER_STYLE_NONE;
mBorderStyle[1] = NS_STYLE_BORDER_STYLE_NONE;
mBorderStyle[2] = NS_STYLE_BORDER_STYLE_NONE;
mBorderStyle[3] = NS_STYLE_BORDER_STYLE_NONE;
mBorderColor[0] = NS_RGB(0, 0, 0);
mBorderColor[1] = NS_RGB(0, 0, 0);
mBorderColor[2] = NS_RGB(0, 0, 0);
mBorderColor[3] = NS_RGB(0, 0, 0);
mBorderRadius.Reset();
mOutlineRadius.Reset();
mOutlineWidth = medium;
mOutlineStyle = NS_STYLE_BORDER_STYLE_NONE;
mOutlineColor = NS_RGB(0, 0, 0);
mFloatEdge = NS_STYLE_FLOAT_EDGE_CONTENT;
mHasCachedMargin = PR_FALSE;
mHasCachedPadding = PR_FALSE;
mHasCachedBorder = PR_FALSE;
mHasCachedOutline = PR_FALSE;
1998-04-21 04:02:44 +04:00
}
void StyleSpacingImpl::SetFrom(const nsStyleSpacing& aSource)
{
nsCRT::memcpy((nsStyleSpacing*)this, &aSource, sizeof(nsStyleSpacing));
}
void StyleSpacingImpl::CopyTo(nsStyleSpacing& aDest) const
{
nsCRT::memcpy(&aDest, (const nsStyleSpacing*)this, sizeof(nsStyleSpacing));
}
static PRBool IsFixedData(const nsStyleSides& aSides, PRBool aEnumOK)
1998-04-21 04:02:44 +04:00
{
return PRBool(IsFixedUnit(aSides.GetLeftUnit(), aEnumOK) &&
IsFixedUnit(aSides.GetTopUnit(), aEnumOK) &&
IsFixedUnit(aSides.GetRightUnit(), aEnumOK) &&
IsFixedUnit(aSides.GetBottomUnit(), aEnumOK));
1998-04-21 04:02:44 +04:00
}
static nscoord CalcCoord(const nsStyleCoord& aCoord,
const nscoord* aEnumTable,
PRInt32 aNumEnums)
{
switch (aCoord.GetUnit()) {
case eStyleUnit_Null:
return 0;
case eStyleUnit_Coord:
return aCoord.GetCoordValue();
case eStyleUnit_Enumerated:
if (nsnull != aEnumTable) {
PRInt32 value = aCoord.GetIntValue();
if ((0 <= value) && (value < aNumEnums)) {
return aEnumTable[aCoord.GetIntValue()];
}
}
break;
default:
NS_ERROR("bad unit type");
break;
}
return 0;
}
1998-04-21 04:02:44 +04:00
PRBool StyleSpacingImpl::IsBorderSideVisible(PRUint8 aSide) const
{
PRUint8 borderStyle = GetBorderStyle(aSide);
return ((borderStyle != NS_STYLE_BORDER_STYLE_NONE)
&& (borderStyle != NS_STYLE_BORDER_STYLE_HIDDEN));
}
void StyleSpacingImpl::RecalcData(nsIPresContext* aPresContext, nscolor aColor)
{
nscoord borderWidths[3];
float pixelsToTwips = 20.0f;
if (aPresContext) {
aPresContext->GetPixelsToTwips(&pixelsToTwips);
}
borderWidths[NS_STYLE_BORDER_WIDTH_THIN] = NSIntPixelsToTwips(1, pixelsToTwips);
borderWidths[NS_STYLE_BORDER_WIDTH_MEDIUM] = NSIntPixelsToTwips(3, pixelsToTwips);
borderWidths[NS_STYLE_BORDER_WIDTH_THICK] = NSIntPixelsToTwips(5, pixelsToTwips);
if (IsFixedData(mMargin, PR_FALSE)) {
nsStyleCoord coord;
mCachedMargin.left = CalcCoord(mMargin.GetLeft(coord), nsnull, 0);
mCachedMargin.top = CalcCoord(mMargin.GetTop(coord), nsnull, 0);
mCachedMargin.right = CalcCoord(mMargin.GetRight(coord), nsnull, 0);
mCachedMargin.bottom = CalcCoord(mMargin.GetBottom(coord), nsnull, 0);
mHasCachedMargin = PR_TRUE;
}
else {
mHasCachedMargin = PR_FALSE;
}
1998-04-21 04:02:44 +04:00
if (IsFixedData(mPadding, PR_FALSE)) {
nsStyleCoord coord;
mCachedPadding.left = CalcCoord(mPadding.GetLeft(coord), nsnull, 0);
mCachedPadding.top = CalcCoord(mPadding.GetTop(coord), nsnull, 0);
mCachedPadding.right = CalcCoord(mPadding.GetRight(coord), nsnull, 0);
mCachedPadding.bottom = CalcCoord(mPadding.GetBottom(coord), nsnull, 0);
mHasCachedPadding = PR_TRUE;
}
else {
mHasCachedPadding = PR_FALSE;
}
if (((!IsBorderSideVisible(NS_SIDE_LEFT))||
IsFixedUnit(mBorder.GetLeftUnit(), PR_TRUE)) &&
((!IsBorderSideVisible(NS_SIDE_TOP)) ||
IsFixedUnit(mBorder.GetTopUnit(), PR_TRUE)) &&
((!IsBorderSideVisible(NS_SIDE_RIGHT)) ||
IsFixedUnit(mBorder.GetRightUnit(), PR_TRUE)) &&
((!IsBorderSideVisible(NS_SIDE_BOTTOM)) ||
IsFixedUnit(mBorder.GetBottomUnit(), PR_TRUE))) {
nsStyleCoord coord;
if (!IsBorderSideVisible(NS_SIDE_LEFT)) {
mCachedBorder.left = 0;
}
else {
mCachedBorder.left = CalcCoord(mBorder.GetLeft(coord), borderWidths, 3);
}
if (!IsBorderSideVisible(NS_SIDE_TOP)) {
mCachedBorder.top = 0;
}
else {
mCachedBorder.top = CalcCoord(mBorder.GetTop(coord), borderWidths, 3);
}
if (!IsBorderSideVisible(NS_SIDE_RIGHT)) {
mCachedBorder.right = 0;
}
else {
mCachedBorder.right = CalcCoord(mBorder.GetRight(coord), borderWidths, 3);
}
if (!IsBorderSideVisible(NS_SIDE_BOTTOM)) {
mCachedBorder.bottom = 0;
}
else {
mCachedBorder.bottom = CalcCoord(mBorder.GetBottom(coord), borderWidths, 3);
}
mHasCachedBorder = PR_TRUE;
}
else {
mHasCachedBorder = PR_FALSE;
}
if (mHasCachedBorder && mHasCachedPadding) {
mCachedBorderPadding = mCachedPadding;
mCachedBorderPadding += mCachedBorder;
}
if ((mBorderStyle[NS_SIDE_TOP] & BORDER_COLOR_DEFINED) == 0) {
mBorderColor[NS_SIDE_TOP] = aColor;
}
if ((mBorderStyle[NS_SIDE_BOTTOM] & BORDER_COLOR_DEFINED) == 0) {
mBorderColor[NS_SIDE_BOTTOM] = aColor;
}
if ((mBorderStyle[NS_SIDE_LEFT]& BORDER_COLOR_DEFINED) == 0) {
mBorderColor[NS_SIDE_LEFT] = aColor;
}
if ((mBorderStyle[NS_SIDE_RIGHT] & BORDER_COLOR_DEFINED) == 0) {
mBorderColor[NS_SIDE_RIGHT] = aColor;
}
1998-04-21 04:02:44 +04:00
if ((NS_STYLE_BORDER_STYLE_NONE == GetOutlineStyle()) ||
IsFixedUnit(mOutlineWidth.GetUnit(), PR_TRUE)) {
if (NS_STYLE_BORDER_STYLE_NONE == GetOutlineStyle()) {
mCachedOutlineWidth = 0;
}
else {
mCachedOutlineWidth = CalcCoord(mOutlineWidth, borderWidths, 3);
}
mHasCachedOutline = PR_TRUE;
}
else {
mHasCachedOutline = PR_FALSE;
}
1998-04-21 04:02:44 +04:00
}
1999-02-27 10:11:42 +03:00
PRInt32 StyleSpacingImpl::CalcDifference(const StyleSpacingImpl& aOther) const
{
if ((mMargin == aOther.mMargin) &&
(mPadding == aOther.mPadding) &&
(mBorder == aOther.mBorder) &&
1999-09-17 04:57:06 +04:00
(mFloatEdge == aOther.mFloatEdge)) {
PRInt32 ix;
for (ix = 0; ix < 4; ix++) {
if ((mBorderStyle[ix] != aOther.mBorderStyle[ix]) ||
(mBorderColor[ix] != aOther.mBorderColor[ix])) {
if ((mBorderStyle[ix] != aOther.mBorderStyle[ix]) &&
((NS_STYLE_BORDER_STYLE_NONE == mBorderStyle[ix]) ||
(NS_STYLE_BORDER_STYLE_NONE == aOther.mBorderStyle[ix]) ||
(NS_STYLE_BORDER_STYLE_HIDDEN == mBorderStyle[ix]) || // bug 45754
(NS_STYLE_BORDER_STYLE_HIDDEN == aOther.mBorderStyle[ix]))) {
1999-05-19 03:03:29 +04:00
return NS_STYLE_HINT_REFLOW; // border on or off
}
1999-02-27 10:11:42 +03:00
return NS_STYLE_HINT_VISUAL;
}
}
if (mBorderRadius != aOther.mBorderRadius) {
return NS_STYLE_HINT_VISUAL;
}
if ((mOutlineWidth != aOther.mOutlineWidth) ||
(mOutlineStyle != aOther.mOutlineStyle) ||
(mOutlineColor != aOther.mOutlineColor) ||
(mOutlineRadius != aOther.mOutlineRadius)) {
Landing changes Vidur made while the tree was closed for beta1 work, here's a list of the changes. r=me [1] Cutting down the size of content. Made nsIJSScriptObject inherit from nsIScriptObjectOwner [2] Cutting down the size of content. Made nsITextContent inherit from nsIContent. [3] Cutting down the size of content. Moved implementation of nsIDOMReceiver to nsListenerManager. This is not true aggregation since it isn't transitive, but it's OK for now. It will be necessary for nsListenerManager to have a reference to its content in the future anyway, so the transitivity could be done. dom/public/nsDOMPropEnums.h,v - bug 12559 dom/public/nsIJSScriptObject.h,v - [1] dom/public/html/MANIFEST,v - bug 12559 dom/public/html/Makefile.in,v - bug 12559 dom/public/html/makefile.win,v - bug 12559 dom/public/html/nsIDOMHTMLInputElement.h,v - bug 17544 dom/public/idl/html/HTMLAnchorElement.idl,v - bug 12559 dom/public/idl/html/HTMLAreaElement.idl,v - bug 12559 dom/public/idl/html/HTMLInputElement.idl,v - bug 17544 dom/src/base/nsGlobalWindow.cpp,v - bug 30700 dom/src/base/nsGlobalWindow.h,v - [1] dom/src/base/nsLocation.cpp,v - [1] dom/src/html/nsJSHTMLAnchorElement.cpp,v - bug 12559 dom/src/html/nsJSHTMLAreaElement.cpp,v - bug 12559 dom/src/html/nsJSHTMLInputElement.cpp,v - bug 17544 layout/base/public/nsIDocument.h,v - bug 27953 layout/base/public/nsITextContent.h,v - [2] layout/base/src/nsCommentNode.cpp,v - [2] layout/base/src/nsDocument.cpp,v - bug 27953 layout/base/src/nsDocument.h,v - bug 27953 layout/base/src/nsDocumentViewer.cpp,v - bug 27953 layout/base/src/nsGenericDOMDataNode.cpp,v - [3] layout/base/src/nsGenericDOMDataNode.h,v - [3] layout/base/src/nsGenericElement.cpp,v - [3] layout/base/src/nsGenericElement.h,v - [3] layout/base/src/nsNameSpaceManager.cpp,v - bug 7834 layout/base/src/nsStyleContext.cpp,v - outline property shouldn't reflow layout/base/src/nsTextNode.cpp,v - [2] layout/events/src/nsEventListenerManager.cpp,v - [3] layout/events/src/nsEventListenerManager.h,v - [3] layout/html/base/src/nsGfxScrollFrame.cpp,v - nsString->nsAutoString layout/html/content/src/nsAttributeContent.cpp,v - [2] layout/html/content/src/nsHTMLAnchorElement.cpp,v - [1][3] layout/html/content/src/nsHTMLAppletElement.cpp,v - [1][3] layout/html/content/src/nsHTMLAreaElement.cpp,v - [1][3] layout/html/content/src/nsHTMLBRElement.cpp,v - [1][3] layout/html/content/src/nsHTMLBaseElement.cpp,v - [1][3] layout/html/content/src/nsHTMLBaseFontElement.cpp,v - [1][3] layout/html/content/src/nsHTMLBodyElement.cpp,v - [1][3] layout/html/content/src/nsHTMLButtonElement.cpp,v - [1][3] layout/html/content/src/nsHTMLDListElement.cpp,v - [1][3] layout/html/content/src/nsHTMLDelElement.cpp,v - [1][3] layout/html/content/src/nsHTMLDirectoryElement.cpp,v - [1][3] layout/html/content/src/nsHTMLDivElement.cpp,v - [1][3] layout/html/content/src/nsHTMLEmbedElement.cpp,v - [1][3] layout/html/content/src/nsHTMLFieldSetElement.cpp,v - [1][3] layout/html/content/src/nsHTMLFontElement.cpp,v - [1][3] layout/html/content/src/nsHTMLFormElement.cpp,v - [1][3] layout/html/content/src/nsHTMLFrameElement.cpp,v - [1][3] layout/html/content/src/nsHTMLFrameSetElement.cpp,v - [1][3] layout/html/content/src/nsHTMLHRElement.cpp,v - [1][3] layout/html/content/src/nsHTMLHeadElement.cpp,v - [1][3] layout/html/content/src/nsHTMLHeadingElement.cpp,v - [1][3] layout/html/content/src/nsHTMLHtmlElement.cpp,v - [1][3] layout/html/content/src/nsHTMLIFrameElement.cpp,v - [1][3] layout/html/content/src/nsHTMLImageElement.cpp,v - [1][3] layout/html/content/src/nsHTMLInputElement.cpp,v - [1][3] layout/html/content/src/nsHTMLInsElement.cpp,v - [1][3] layout/html/content/src/nsHTMLIsIndexElement.cpp,v - [1][3] layout/html/content/src/nsHTMLLIElement.cpp,v - [1][3] layout/html/content/src/nsHTMLLabelElement.cpp,v - [1][3] layout/html/content/src/nsHTMLLayerElement.cpp,v - [1][3] layout/html/content/src/nsHTMLLegendElement.cpp,v - [1][3] layout/html/content/src/nsHTMLLinkElement.cpp,v - [1][3] layout/html/content/src/nsHTMLMapElement.cpp,v - [1][3] layout/html/content/src/nsHTMLMenuElement.cpp,v - [1][3] layout/html/content/src/nsHTMLMetaElement.cpp,v - [1][3] layout/html/content/src/nsHTMLModElement.cpp,v - [1][3] layout/html/content/src/nsHTMLOListElement.cpp,v - [1][3] layout/html/content/src/nsHTMLObjectElement.cpp,v - [1][3] layout/html/content/src/nsHTMLOptGroupElement.cpp,v - [1][3] layout/html/content/src/nsHTMLOptionElement.cpp,v - [1][3] layout/html/content/src/nsHTMLParagraphElement.cpp,v - [1][3] layout/html/content/src/nsHTMLParamElement.cpp,v - [1][3] layout/html/content/src/nsHTMLPreElement.cpp,v - [1][3] layout/html/content/src/nsHTMLQuoteElement.cpp,v - [1][3] layout/html/content/src/nsHTMLScriptElement.cpp,v - [1][3] layout/html/content/src/nsHTMLSelectElement.cpp,v - [1][3] layout/html/content/src/nsHTMLSpacerElement.cpp,v - [1][3] layout/html/content/src/nsHTMLSpanElement.cpp,v - [1][3] layout/html/content/src/nsHTMLStyleElement.cpp,v - [1][3] layout/html/content/src/nsHTMLTableCaptionElement.cpp,v - [1][3] layout/html/content/src/nsHTMLTableCellElement.cpp,v - [1][3] layout/html/content/src/nsHTMLTableColElement.cpp,v - [1][3] layout/html/content/src/nsHTMLTableColGroupElement.cpp,v - [1][3] layout/html/content/src/nsHTMLTableElement.cpp,v - [1][3] layout/html/content/src/nsHTMLTableRowElement.cpp,v - [1][3] layout/html/content/src/nsHTMLTableSectionElement.cpp,v - [1][3] layout/html/content/src/nsHTMLTextAreaElement.cpp,v - [1][3] layout/html/content/src/nsHTMLTitleElement.cpp,v - [1][3] layout/html/content/src/nsHTMLUListElement.cpp,v - [1][3] layout/html/content/src/nsHTMLWBRElement.cpp,v - [1][3] layout/html/document/src/nsHTMLDocument.cpp,v - bug 27953 layout/html/document/src/nsHTMLDocument.h,v - bug 27953 layout/xml/content/src/nsXMLCDATASection.cpp,v - [1][2] layout/xml/content/src/nsXMLDocumentType.cpp,v - [1][2] layout/xml/content/src/nsXMLElement.h,v - [1][2] layout/xml/content/src/nsXMLEntity.cpp,v - [1][2] layout/xml/content/src/nsXMLNotation.cpp,v - [1][2] layout/xml/content/src/nsXMLProcessingInstruction.cpp,v - [1][2] layout/xul/base/src/nsBoxFrame.cpp,v - nsString->nsAutoString layout/xul/base/src/nsSliderFrame.cpp,v - nsString->nsAutoString netwerk/protocol/http/src/nsHTTPRequest.cpp,v - nsString->nsAutoString rdf/content/src/nsXULDocument.cpp,v - bug 27953 rdf/content/src/nsXULDocument.h,v - bug 27953 rdf/content/src/nsXULElement.h,v - [1] xpcom/base/IIDS.h,v - bug 12559
2000-03-17 16:27:00 +03:00
return NS_STYLE_HINT_VISUAL; // XXX: should be VISUAL: see bugs 9809 and 9816
}
1999-02-27 10:11:42 +03:00
return NS_STYLE_HINT_NONE;
}
return NS_STYLE_HINT_REFLOW;
}
PRUint32 StyleSpacingImpl::ComputeCRC32(PRUint32 aCrc) const
{
PRUint32 crc = aCrc;
#ifdef COMPUTE_STYLEDATA_CRC
crc = StyleSideCRC(crc,&mMargin);
crc = StyleSideCRC(crc,&mPadding);
crc = StyleSideCRC(crc,&mBorder);
crc = StyleSideCRC(crc,&mBorderRadius);
crc = StyleSideCRC(crc,&mOutlineRadius);
crc = StyleCoordCRC(crc,&mOutlineWidth);
crc = AccumulateCRC(crc,(const char *)&mFloatEdge,sizeof(mFloatEdge));
crc = AccumulateCRC(crc,(const char *)&mHasCachedMargin,sizeof(mHasCachedMargin));
crc = AccumulateCRC(crc,(const char *)&mHasCachedPadding,sizeof(mHasCachedPadding));
crc = AccumulateCRC(crc,(const char *)&mHasCachedBorder,sizeof(mHasCachedBorder));
crc = AccumulateCRC(crc,(const char *)&mHasCachedOutline,sizeof(mHasCachedOutline));
crc = StyleMarginCRC(crc,&mCachedMargin);
crc = StyleMarginCRC(crc,&mCachedPadding);
crc = StyleMarginCRC(crc,&mCachedBorder);
crc = StyleMarginCRC(crc,&mCachedBorderPadding);
crc = AccumulateCRC(crc,(const char *)&mCachedOutlineWidth,sizeof(mCachedOutlineWidth));
crc = AccumulateCRC(crc,(const char *)mBorderStyle,sizeof(mBorderStyle)); // array of 4 elements
crc = AccumulateCRC(crc,(const char *)mBorderColor,sizeof(mBorderColor)); // array ...
crc = AccumulateCRC(crc,(const char *)&mOutlineStyle,sizeof(mOutlineStyle));
crc = AccumulateCRC(crc,(const char *)&mOutlineColor,sizeof(mOutlineColor));
#endif
return crc;
}
1998-04-21 04:02:44 +04:00
// --------------------
// nsStyleList
//
nsStyleList::nsStyleList(void) { }
nsStyleList::~nsStyleList(void) { }
1998-04-14 00:24:54 +04:00
struct StyleListImpl: public nsStyleList {
StyleListImpl(void) { }
1998-04-14 00:24:54 +04:00
void ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresContext);
void SetFrom(const nsStyleList& aSource);
void CopyTo(nsStyleList& aDest) const;
1999-02-27 10:11:42 +03:00
PRInt32 CalcDifference(const StyleListImpl& aOther) const;
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
1998-04-14 00:24:54 +04:00
};
void StyleListImpl::ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresContext)
1998-04-14 00:24:54 +04:00
{
if (nsnull != aParent) {
mListStyleType = aParent->mListStyleType;
mListStyleImage = aParent->mListStyleImage;
mListStylePosition = aParent->mListStylePosition;
}
else {
mListStyleType = NS_STYLE_LIST_STYLE_BASIC;
mListStylePosition = NS_STYLE_LIST_STYLE_POSITION_OUTSIDE;
mListStyleImage.Truncate();
}
1998-04-14 00:24:54 +04:00
}
void StyleListImpl::SetFrom(const nsStyleList& aSource)
{
mListStyleType = aSource.mListStyleType;
mListStylePosition = aSource.mListStylePosition;
mListStyleImage = aSource.mListStyleImage;
}
void StyleListImpl::CopyTo(nsStyleList& aDest) const
{
aDest.mListStyleType = mListStyleType;
aDest.mListStylePosition = mListStylePosition;
aDest.mListStyleImage = mListStyleImage;
}
1999-02-27 10:11:42 +03:00
PRInt32 StyleListImpl::CalcDifference(const StyleListImpl& aOther) const
{
if (mListStylePosition == aOther.mListStylePosition) {
if (mListStyleImage == aOther.mListStyleImage) {
if (mListStyleType == aOther.mListStyleType) {
return NS_STYLE_HINT_NONE;
}
return NS_STYLE_HINT_REFLOW;
1999-02-27 10:11:42 +03:00
}
return NS_STYLE_HINT_REFLOW;
1999-02-27 10:11:42 +03:00
}
return NS_STYLE_HINT_REFLOW;
}
PRUint32 StyleListImpl::ComputeCRC32(PRUint32 aCrc) const
{
PRUint32 crc = aCrc;
#ifdef COMPUTE_STYLEDATA_CRC
crc = AccumulateCRC(crc,(const char *)&mListStyleType,sizeof(mListStyleType));
crc = AccumulateCRC(crc,(const char *)&mListStylePosition,sizeof(mListStylePosition));
crc = StyleStringCRC(crc,&mListStyleImage);
#endif
return crc;
}
1999-02-27 10:11:42 +03:00
1998-04-23 03:29:01 +04:00
// --------------------
// nsStylePosition
//
nsStylePosition::nsStylePosition(void) { }
1998-04-23 03:29:01 +04:00
struct StylePositionImpl: public nsStylePosition {
StylePositionImpl(void) { }
1998-04-23 03:29:01 +04:00
void ResetFrom(const nsStylePosition* aParent, nsIPresContext* aPresContext);
void SetFrom(const nsStylePosition& aSource);
void CopyTo(nsStylePosition& aDest) const;
1999-02-27 10:11:42 +03:00
PRInt32 CalcDifference(const StylePositionImpl& aOther) const;
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
1998-04-23 03:29:01 +04:00
private: // These are not allowed
StylePositionImpl(const StylePositionImpl& aOther);
StylePositionImpl& operator=(const StylePositionImpl& aOther);
};
void StylePositionImpl::ResetFrom(const nsStylePosition* aParent, nsIPresContext* aPresContext)
1998-04-23 03:29:01 +04:00
{
// positioning values not inherited
mPosition = NS_STYLE_POSITION_NORMAL;
nsStyleCoord autoCoord(eStyleUnit_Auto);
mOffset.SetLeft(autoCoord);
mOffset.SetTop(autoCoord);
mOffset.SetRight(autoCoord);
mOffset.SetBottom(autoCoord);
mWidth.SetAutoValue();
mMinWidth.SetCoordValue(0);
mMaxWidth.Reset();
mHeight.SetAutoValue();
mMinHeight.SetCoordValue(0);
mMaxHeight.Reset();
mBoxSizing = NS_STYLE_BOX_SIZING_CONTENT;
mZIndex.SetAutoValue();
1998-04-23 03:29:01 +04:00
}
void StylePositionImpl::SetFrom(const nsStylePosition& aSource)
{
nsCRT::memcpy((nsStylePosition*)this, &aSource, sizeof(nsStylePosition));
}
void StylePositionImpl::CopyTo(nsStylePosition& aDest) const
{
nsCRT::memcpy(&aDest, (const nsStylePosition*)this, sizeof(nsStylePosition));
}
1999-02-27 10:11:42 +03:00
PRInt32 StylePositionImpl::CalcDifference(const StylePositionImpl& aOther) const
{
if (mPosition == aOther.mPosition) {
if ((mOffset == aOther.mOffset) &&
(mWidth == aOther.mWidth) &&
(mMinWidth == aOther.mMinWidth) &&
(mMaxWidth == aOther.mMaxWidth) &&
(mHeight == aOther.mHeight) &&
(mMinHeight == aOther.mMinHeight) &&
(mMaxHeight == aOther.mMaxHeight) &&
(mBoxSizing == aOther.mBoxSizing) &&
1999-02-27 10:11:42 +03:00
(mZIndex == aOther.mZIndex)) {
return NS_STYLE_HINT_NONE;
}
return NS_STYLE_HINT_REFLOW;
}
return NS_STYLE_HINT_FRAMECHANGE;
}
PRUint32 StylePositionImpl::ComputeCRC32(PRUint32 aCrc) const
{
PRUint32 crc = aCrc;
#ifdef COMPUTE_STYLEDATA_CRC
crc = AccumulateCRC(crc,(const char *)&mPosition,sizeof(mPosition));
crc = StyleSideCRC(crc,&mOffset);
crc = StyleCoordCRC(crc,&mWidth);
crc = StyleCoordCRC(crc,&mMinWidth);
crc = StyleCoordCRC(crc,&mMaxWidth);
crc = StyleCoordCRC(crc,&mHeight);
crc = StyleCoordCRC(crc,&mMinHeight);
crc = StyleCoordCRC(crc,&mMaxHeight);
crc = AccumulateCRC(crc,(const char *)&mBoxSizing,sizeof(mBoxSizing));
crc = AccumulateCRC(crc,(const char *)&mZIndex,sizeof(mZIndex));
#endif
return crc;
}
1998-04-21 04:02:44 +04:00
// --------------------
// nsStyleText
1998-04-21 04:02:44 +04:00
//
1998-04-14 00:24:54 +04:00
nsStyleText::nsStyleText(void) { }
struct StyleTextImpl: public nsStyleText {
StyleTextImpl(void) { }
void ResetFrom(const nsStyleText* aParent, nsIPresContext* aPresContext);
void SetFrom(const nsStyleText& aSource);
void CopyTo(nsStyleText& aDest) const;
1999-02-27 10:11:42 +03:00
PRInt32 CalcDifference(const StyleTextImpl& aOther) const;
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
};
void StyleTextImpl::ResetFrom(const nsStyleText* aParent, nsIPresContext* aPresContext)
{
// These properties not inherited
mTextDecoration = NS_STYLE_TEXT_DECORATION_NONE;
mVerticalAlign.SetIntValue(NS_STYLE_VERTICAL_ALIGN_BASELINE, eStyleUnit_Enumerated);
// mVerticalAlign.Reset(); TBI
if (nsnull != aParent) {
mTextAlign = aParent->mTextAlign;
mTextTransform = aParent->mTextTransform;
mWhiteSpace = aParent->mWhiteSpace;
mLetterSpacing = aParent->mLetterSpacing;
// Inherit everything except percentage line-height values
nsStyleUnit unit = aParent->mLineHeight.GetUnit();
if ((eStyleUnit_Normal == unit) || (eStyleUnit_Factor == unit) ||
(eStyleUnit_Coord == unit)) {
mLineHeight = aParent->mLineHeight;
}
else {
mLineHeight.SetInheritValue();
}
mTextIndent = aParent->mTextIndent;
mWordSpacing = aParent->mWordSpacing;
}
else {
mTextAlign = NS_STYLE_TEXT_ALIGN_DEFAULT;
mTextTransform = NS_STYLE_TEXT_TRANSFORM_NONE;
mWhiteSpace = NS_STYLE_WHITESPACE_NORMAL;
mLetterSpacing.SetNormalValue();
mLineHeight.SetNormalValue();
mTextIndent.SetCoordValue(0);
mWordSpacing.SetNormalValue();
}
}
void StyleTextImpl::SetFrom(const nsStyleText& aSource)
{
nsCRT::memcpy((nsStyleText*)this, &aSource, sizeof(nsStyleText));
}
void StyleTextImpl::CopyTo(nsStyleText& aDest) const
{
nsCRT::memcpy(&aDest, (const nsStyleText*)this, sizeof(nsStyleText));
1998-04-14 00:24:54 +04:00
}
1999-02-27 10:11:42 +03:00
PRInt32 StyleTextImpl::CalcDifference(const StyleTextImpl& aOther) const
{
if ((mTextAlign == aOther.mTextAlign) &&
(mTextTransform == aOther.mTextTransform) &&
(mWhiteSpace == aOther.mWhiteSpace) &&
(mLetterSpacing == aOther.mLetterSpacing) &&
(mLineHeight == aOther.mLineHeight) &&
(mTextIndent == aOther.mTextIndent) &&
(mWordSpacing == aOther.mWordSpacing) &&
(mVerticalAlign == aOther.mVerticalAlign)) {
if (mTextDecoration == aOther.mTextDecoration) {
return NS_STYLE_HINT_NONE;
}
return NS_STYLE_HINT_VISUAL;
}
return NS_STYLE_HINT_REFLOW;
}
PRUint32 StyleTextImpl::ComputeCRC32(PRUint32 aCrc) const
{
PRUint32 crc = aCrc;
#ifdef COMPUTE_STYLEDATA_CRC
crc = AccumulateCRC(crc,(const char *)&mTextAlign,sizeof(mTextAlign));
crc = AccumulateCRC(crc,(const char *)&mTextDecoration,sizeof(mTextDecoration));
crc = AccumulateCRC(crc,(const char *)&mTextTransform,sizeof(mTextTransform));
crc = AccumulateCRC(crc,(const char *)&mWhiteSpace,sizeof(mWhiteSpace));
crc = StyleCoordCRC(crc,&mLetterSpacing);
crc = StyleCoordCRC(crc,&mLineHeight);
crc = StyleCoordCRC(crc,&mTextIndent);
crc = StyleCoordCRC(crc,&mWordSpacing);
crc = StyleCoordCRC(crc,&mVerticalAlign);
#endif
return crc;
}
// --------------------
// nsStyleDisplay
//
1998-04-14 00:24:54 +04:00
nsStyleDisplay::nsStyleDisplay(void) { }
struct StyleDisplayImpl: public nsStyleDisplay {
StyleDisplayImpl(void) { }
1998-04-14 00:24:54 +04:00
void ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* aPresContext);
void SetFrom(const nsStyleDisplay& aSource);
void CopyTo(nsStyleDisplay& aDest) const;
1999-02-27 10:11:42 +03:00
PRInt32 CalcDifference(const StyleDisplayImpl& aOther) const;
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
1998-04-14 00:24:54 +04:00
};
void StyleDisplayImpl::ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* aPresContext)
1998-04-14 00:24:54 +04:00
{
if (nsnull != aParent) {
mDirection = aParent->mDirection;
mLanguage = aParent->mLanguage;
mVisible = aParent->mVisible;
}
else {
aPresContext->GetDefaultDirection(&mDirection);
aPresContext->GetLanguage(getter_AddRefs(mLanguage));
1999-02-02 06:24:23 +03:00
mVisible = NS_STYLE_VISIBILITY_VISIBLE;
}
mDisplay = NS_STYLE_DISPLAY_INLINE;
mFloats = NS_STYLE_FLOAT_NONE;
mBreakType = NS_STYLE_CLEAR_NONE;
mBreakBefore = PR_FALSE;
mBreakAfter = PR_FALSE;
mOverflow = NS_STYLE_OVERFLOW_VISIBLE;
mClipFlags = NS_STYLE_CLIP_AUTO;
mClip.SetRect(0,0,0,0);
1998-04-14 00:24:54 +04:00
}
void StyleDisplayImpl::SetFrom(const nsStyleDisplay& aSource)
{
mDirection = aSource.mDirection;
mDisplay = aSource.mDisplay;
mFloats = aSource.mFloats;
mBreakType = aSource.mBreakType;
mBreakBefore = aSource.mBreakBefore;
mBreakAfter = aSource.mBreakAfter;
mVisible = aSource.mVisible;
mOverflow = aSource.mOverflow;
mClipFlags = aSource.mClipFlags;
mClip = aSource.mClip;
mLanguage = aSource.mLanguage;
}
void StyleDisplayImpl::CopyTo(nsStyleDisplay& aDest) const
{
aDest.mDirection = mDirection;
aDest.mDisplay = mDisplay;
aDest.mFloats = mFloats;
aDest.mBreakType = mBreakType;
aDest.mBreakBefore = mBreakBefore;
aDest.mBreakAfter = mBreakAfter;
aDest.mVisible = mVisible;
aDest.mOverflow = mOverflow;
aDest.mClipFlags = mClipFlags;
aDest.mClip = mClip;
aDest.mLanguage = mLanguage;
}
1999-02-27 10:11:42 +03:00
PRInt32 StyleDisplayImpl::CalcDifference(const StyleDisplayImpl& aOther) const
{
if ((mDisplay == aOther.mDisplay) &&
(mFloats == aOther.mFloats) &&
(mOverflow == aOther.mOverflow)) {
if ((mDirection == aOther.mDirection) &&
(mLanguage == aOther.mLanguage) &&
1999-02-27 10:11:42 +03:00
(mBreakType == aOther.mBreakType) &&
(mBreakBefore == aOther.mBreakBefore) &&
(mBreakAfter == aOther.mBreakAfter)) {
if ((mVisible == aOther.mVisible) &&
(mClipFlags == aOther.mClipFlags) &&
(mClip == aOther.mClip)) {
return NS_STYLE_HINT_NONE;
}
if ((mVisible != aOther.mVisible) &&
((NS_STYLE_VISIBILITY_COLLAPSE == mVisible) ||
(NS_STYLE_VISIBILITY_COLLAPSE == aOther.mVisible))) {
return NS_STYLE_HINT_REFLOW;
}
1999-02-27 10:11:42 +03:00
return NS_STYLE_HINT_VISUAL;
}
return NS_STYLE_HINT_REFLOW;
}
return NS_STYLE_HINT_FRAMECHANGE;
}
PRUint32 StyleDisplayImpl::ComputeCRC32(PRUint32 aCrc) const
{
PRUint32 crc = aCrc;
#ifdef COMPUTE_STYLEDATA_CRC
crc = AccumulateCRC(crc,(const char *)&mDirection,sizeof(mDirection));
crc = AccumulateCRC(crc,(const char *)&mDisplay,sizeof(mDisplay));
crc = AccumulateCRC(crc,(const char *)&mFloats,sizeof(mFloats));
crc = AccumulateCRC(crc,(const char *)&mBreakType,sizeof(mBreakType));
crc = AccumulateCRC(crc,(const char *)&mBreakBefore,sizeof(mBreakBefore));
crc = AccumulateCRC(crc,(const char *)&mBreakAfter,sizeof(mBreakAfter));
crc = AccumulateCRC(crc,(const char *)&mVisible,sizeof(mVisible));
crc = AccumulateCRC(crc,(const char *)&mOverflow,sizeof(mOverflow));
crc = AccumulateCRC(crc,(const char *)&mClipFlags,sizeof(mClipFlags));
// crc = StyleMarginCRC(crc,&mClip);
#endif
return crc;
}
// --------------------
// nsStyleTable
//
nsStyleTable::nsStyleTable(void) { }
struct StyleTableImpl: public nsStyleTable {
StyleTableImpl(void);
void ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPresContext);
void SetFrom(const nsStyleTable& aSource);
void CopyTo(nsStyleTable& aDest) const;
1999-02-27 10:11:42 +03:00
PRInt32 CalcDifference(const StyleTableImpl& aOther) const;
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
};
StyleTableImpl::StyleTableImpl()
{
ResetFrom(nsnull, nsnull);
}
void StyleTableImpl::ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPresContext)
{
// values not inherited
mLayoutStrategy = NS_STYLE_TABLE_LAYOUT_AUTO;
mCols = NS_STYLE_TABLE_COLS_NONE;
mFrame = NS_STYLE_TABLE_FRAME_NONE;
mRules = NS_STYLE_TABLE_RULES_ALL;
mCellPadding.Reset();
1999-04-02 22:48:55 +04:00
mSpan = 1;
if (aParent) { // handle inherited properties
mBorderCollapse = aParent->mBorderCollapse;
mEmptyCells = aParent->mEmptyCells;
mCaptionSide = aParent->mCaptionSide;
mBorderSpacingX = aParent->mBorderSpacingX;
mBorderSpacingY = aParent->mBorderSpacingY;
mSpanWidth = aParent->mSpanWidth;
}
else {
mBorderCollapse = NS_STYLE_BORDER_SEPARATE;
nsCompatibility compatMode = eCompatibility_Standard;
if (aPresContext) {
aPresContext->GetCompatibilityMode(&compatMode);
}
mEmptyCells = (compatMode == eCompatibility_NavQuirks
? NS_STYLE_TABLE_EMPTY_CELLS_HIDE // bug 33244
: NS_STYLE_TABLE_EMPTY_CELLS_SHOW);
1999-04-02 22:48:55 +04:00
mCaptionSide = NS_SIDE_TOP;
mBorderSpacingX.Reset();
mBorderSpacingY.Reset();
mSpanWidth.Reset();
}
}
void StyleTableImpl::SetFrom(const nsStyleTable& aSource)
{
nsCRT::memcpy((nsStyleTable*)this, &aSource, sizeof(nsStyleTable));
}
void StyleTableImpl::CopyTo(nsStyleTable& aDest) const
{
nsCRT::memcpy(&aDest, (const nsStyleTable*)this, sizeof(nsStyleTable));
}
1999-02-27 10:11:42 +03:00
PRInt32 StyleTableImpl::CalcDifference(const StyleTableImpl& aOther) const
{
if ((mLayoutStrategy == aOther.mLayoutStrategy) &&
(mFrame == aOther.mFrame) &&
(mRules == aOther.mRules) &&
(mBorderCollapse == aOther.mBorderCollapse) &&
(mBorderSpacingX == aOther.mBorderSpacingX) &&
(mBorderSpacingY == aOther.mBorderSpacingY) &&
(mCellPadding == aOther.mCellPadding) &&
(mCaptionSide == aOther.mCaptionSide) &&
(mCols == aOther.mCols) &&
(mSpan == aOther.mSpan) &&
(mSpanWidth == aOther.mSpanWidth)) {
if (mEmptyCells == aOther.mEmptyCells) {
return NS_STYLE_HINT_NONE;
}
return NS_STYLE_HINT_VISUAL;
}
return NS_STYLE_HINT_REFLOW;
}
PRUint32 StyleTableImpl::ComputeCRC32(PRUint32 aCrc) const
{
PRUint32 crc = aCrc;
#ifdef COMPUTE_STYLEDATA_CRC
crc = AccumulateCRC(crc,(const char *)&mLayoutStrategy,sizeof(mLayoutStrategy));
crc = AccumulateCRC(crc,(const char *)&mFrame,sizeof(mFrame));
crc = AccumulateCRC(crc,(const char *)&mRules,sizeof(mRules));
crc = AccumulateCRC(crc,(const char *)&mBorderCollapse,sizeof(mBorderCollapse));
crc = StyleCoordCRC(crc,&mBorderSpacingX);
crc = StyleCoordCRC(crc,&mBorderSpacingY);
crc = StyleCoordCRC(crc,&mCellPadding);
crc = AccumulateCRC(crc,(const char *)&mCaptionSide,sizeof(mCaptionSide));
crc = AccumulateCRC(crc,(const char *)&mEmptyCells,sizeof(mEmptyCells));
crc = AccumulateCRC(crc,(const char *)&mCols,sizeof(mCols));
crc = AccumulateCRC(crc,(const char *)&mSpan,sizeof(mSpan));
crc = StyleCoordCRC(crc,&mSpanWidth);
#endif
return crc;
}
1999-04-02 22:48:55 +04:00
//-----------------------
// nsStyleContent
//
nsStyleContent::nsStyleContent(void)
: mMarkerOffset(),
mContentCount(0),
mContents(nsnull),
mIncrementCount(0),
mIncrements(nsnull),
mResetCount(0),
mResets(nsnull),
mQuotesCount(0),
mQuotes(nsnull)
{
}
nsStyleContent::~nsStyleContent(void)
{
DELETE_ARRAY_IF(mContents);
DELETE_ARRAY_IF(mIncrements);
DELETE_ARRAY_IF(mResets);
DELETE_ARRAY_IF(mQuotes);
}
nsresult
nsStyleContent::GetContentAt(PRUint32 aIndex, nsStyleContentType& aType, nsString& aContent) const
{
if (aIndex < mContentCount) {
aType = mContents[aIndex].mType;
aContent = mContents[aIndex].mContent;
return NS_OK;
}
return NS_ERROR_ILLEGAL_VALUE;
}
nsresult
nsStyleContent::AllocateContents(PRUint32 aCount)
{
if (aCount != mContentCount) {
DELETE_ARRAY_IF(mContents);
if (aCount) {
mContents = new nsStyleContentData[aCount];
if (! mContents) {
mContentCount = 0;
return NS_ERROR_OUT_OF_MEMORY;
}
}
mContentCount = aCount;
}
return NS_OK;
}
nsresult
nsStyleContent::SetContentAt(PRUint32 aIndex, nsStyleContentType aType, const nsString& aContent)
{
if (aIndex < mContentCount) {
mContents[aIndex].mType = aType;
if (aType < eStyleContentType_OpenQuote) {
mContents[aIndex].mContent = aContent;
}
else {
mContents[aIndex].mContent.Truncate();
}
return NS_OK;
}
return NS_ERROR_ILLEGAL_VALUE;
}
nsresult
nsStyleContent::GetCounterIncrementAt(PRUint32 aIndex, nsString& aCounter, PRInt32& aIncrement) const
{
if (aIndex < mIncrementCount) {
aCounter = mIncrements[aIndex].mCounter;
aIncrement = mIncrements[aIndex].mValue;
return NS_OK;
}
return NS_ERROR_ILLEGAL_VALUE;
}
nsresult
nsStyleContent::AllocateCounterIncrements(PRUint32 aCount)
{
if (aCount != mIncrementCount) {
DELETE_ARRAY_IF(mIncrements);
if (aCount) {
mIncrements = new nsStyleCounterData[aCount];
if (! mIncrements) {
mIncrementCount = 0;
return NS_ERROR_OUT_OF_MEMORY;
}
}
mIncrementCount = aCount;
}
return NS_OK;
}
nsresult
nsStyleContent::SetCounterIncrementAt(PRUint32 aIndex, const nsString& aCounter, PRInt32 aIncrement)
{
if (aIndex < mIncrementCount) {
mIncrements[aIndex].mCounter = aCounter;
mIncrements[aIndex].mValue = aIncrement;
return NS_OK;
}
return NS_ERROR_ILLEGAL_VALUE;
}
nsresult
nsStyleContent::GetCounterResetAt(PRUint32 aIndex, nsString& aCounter, PRInt32& aValue) const
{
if (aIndex < mResetCount) {
aCounter = mResets[aIndex].mCounter;
aValue = mResets[aIndex].mValue;
return NS_OK;
}
return NS_ERROR_ILLEGAL_VALUE;
}
nsresult
nsStyleContent::AllocateCounterResets(PRUint32 aCount)
{
if (aCount != mResetCount) {
DELETE_ARRAY_IF(mResets);
if (aCount) {
mResets = new nsStyleCounterData[aCount];
if (! mResets) {
mResetCount = 0;
return NS_ERROR_OUT_OF_MEMORY;
}
}
mResetCount = aCount;
}
return NS_OK;
}
nsresult
nsStyleContent::SetCounterResetAt(PRUint32 aIndex, const nsString& aCounter, PRInt32 aValue)
{
if (aIndex < mResetCount) {
mResets[aIndex].mCounter = aCounter;
mResets[aIndex].mValue = aValue;
return NS_OK;
}
return NS_ERROR_ILLEGAL_VALUE;
}
nsresult
nsStyleContent::GetQuotesAt(PRUint32 aIndex, nsString& aOpen, nsString& aClose) const
{
if (aIndex < mQuotesCount) {
aIndex *= 2;
aOpen = mQuotes[aIndex];
aClose = mQuotes[++aIndex];
return NS_OK;
}
return NS_ERROR_ILLEGAL_VALUE;
}
nsresult
nsStyleContent::AllocateQuotes(PRUint32 aCount)
{
if (aCount != mQuotesCount) {
DELETE_ARRAY_IF(mQuotes);
if (aCount) {
mQuotes = new nsString[aCount * 2];
if (! mQuotes) {
mQuotesCount = 0;
return NS_ERROR_OUT_OF_MEMORY;
}
}
mQuotesCount = aCount;
}
return NS_OK;
}
nsresult
nsStyleContent::SetQuotesAt(PRUint32 aIndex, const nsString& aOpen, const nsString& aClose)
{
if (aIndex < mQuotesCount) {
aIndex *= 2;
mQuotes[aIndex] = aOpen;
mQuotes[++aIndex] = aClose;
return NS_OK;
}
return NS_ERROR_ILLEGAL_VALUE;
}
struct StyleContentImpl: public nsStyleContent {
StyleContentImpl(void) : nsStyleContent() { };
void ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPresContext);
void SetFrom(const nsStyleContent& aSource);
void CopyTo(nsStyleContent& aDest) const;
1999-04-02 22:48:55 +04:00
PRInt32 CalcDifference(const StyleContentImpl& aOther) const;
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
1999-04-02 22:48:55 +04:00
};
void
StyleContentImpl::ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPresContext)
{
// reset data
mMarkerOffset.Reset();
mContentCount = 0;
DELETE_ARRAY_IF(mContents);
mIncrementCount = 0;
DELETE_ARRAY_IF(mIncrements);
mResetCount = 0;
DELETE_ARRAY_IF(mResets);
// inherited data
if (aParent) {
if (NS_SUCCEEDED(AllocateQuotes(aParent->mQuotesCount))) {
PRUint32 ix = (mQuotesCount * 2);
while (0 < ix--) {
mQuotes[ix] = aParent->mQuotes[ix];
1999-04-02 22:48:55 +04:00
}
}
}
else {
mQuotesCount = 0;
DELETE_ARRAY_IF(mQuotes);
}
}
void StyleContentImpl::SetFrom(const nsStyleContent& aSource)
{
mMarkerOffset = aSource.mMarkerOffset;
PRUint32 index;
if (NS_SUCCEEDED(AllocateContents(aSource.ContentCount()))) {
for (index = 0; index < mContentCount; index++) {
aSource.GetContentAt(index, mContents[index].mType, mContents[index].mContent);
}
}
if (NS_SUCCEEDED(AllocateCounterIncrements(aSource.CounterIncrementCount()))) {
for (index = 0; index < mIncrementCount; index++) {
aSource.GetCounterIncrementAt(index, mIncrements[index].mCounter,
mIncrements[index].mValue);
}
}
if (NS_SUCCEEDED(AllocateCounterResets(aSource.CounterResetCount()))) {
for (index = 0; index < mResetCount; index++) {
aSource.GetCounterResetAt(index, mResets[index].mCounter,
mResets[index].mValue);
}
}
if (NS_SUCCEEDED(AllocateQuotes(aSource.QuotesCount()))) {
PRUint32 count = (mQuotesCount * 2);
for (index = 0; index < count; index += 2) {
aSource.GetQuotesAt(index, mQuotes[index], mQuotes[index + 1]);
}
}
}
void StyleContentImpl::CopyTo(nsStyleContent& aDest) const
{
aDest.mMarkerOffset = mMarkerOffset;
PRUint32 index;
if (NS_SUCCEEDED(aDest.AllocateContents(mContentCount))) {
for (index = 0; index < mContentCount; index++) {
aDest.SetContentAt(index, mContents[index].mType,
mContents[index].mContent);
}
}
if (NS_SUCCEEDED(aDest.AllocateCounterIncrements(mIncrementCount))) {
for (index = 0; index < mIncrementCount; index++) {
aDest.SetCounterIncrementAt(index, mIncrements[index].mCounter,
mIncrements[index].mValue);
}
}
if (NS_SUCCEEDED(aDest.AllocateCounterResets(mResetCount))) {
for (index = 0; index < mResetCount; index++) {
aDest.SetCounterResetAt(index, mResets[index].mCounter,
mResets[index].mValue);
}
}
if (NS_SUCCEEDED(aDest.AllocateQuotes(mQuotesCount))) {
PRUint32 count = (mQuotesCount * 2);
for (index = 0; index < count; index += 2) {
aDest.SetQuotesAt(index, mQuotes[index], mQuotes[index + 1]);
}
}
}
1999-04-02 22:48:55 +04:00
PRInt32
StyleContentImpl::CalcDifference(const StyleContentImpl& aOther) const
{
if (mContentCount == aOther.mContentCount) {
if ((mMarkerOffset == aOther.mMarkerOffset) &&
(mIncrementCount == aOther.mIncrementCount) &&
(mResetCount == aOther.mResetCount) &&
(mQuotesCount == aOther.mQuotesCount)) {
PRUint32 ix = mContentCount;
while (0 < ix--) {
if ((mContents[ix].mType != aOther.mContents[ix].mType) ||
(mContents[ix].mContent != aOther.mContents[ix].mContent)) {
1999-04-02 22:48:55 +04:00
return NS_STYLE_HINT_REFLOW;
}
}
ix = mIncrementCount;
while (0 < ix--) {
if ((mIncrements[ix].mValue != aOther.mIncrements[ix].mValue) ||
(mIncrements[ix].mCounter != aOther.mIncrements[ix].mCounter)) {
1999-04-02 22:48:55 +04:00
return NS_STYLE_HINT_REFLOW;
}
}
ix = mResetCount;
while (0 < ix--) {
if ((mResets[ix].mValue != aOther.mResets[ix].mValue) ||
(mResets[ix].mCounter != aOther.mResets[ix].mCounter)) {
1999-04-02 22:48:55 +04:00
return NS_STYLE_HINT_REFLOW;
}
}
ix = (mQuotesCount * 2);
while (0 < ix--) {
if (mQuotes[ix] != aOther.mQuotes[ix]) {
1999-04-02 22:48:55 +04:00
return NS_STYLE_HINT_REFLOW;
}
}
return NS_STYLE_HINT_NONE;
}
return NS_STYLE_HINT_REFLOW;
}
return NS_STYLE_HINT_FRAMECHANGE;
}
PRUint32 StyleContentImpl::ComputeCRC32(PRUint32 aCrc) const
{
PRUint32 crc = aCrc;
#ifdef COMPUTE_STYLEDATA_CRC
crc = StyleCoordCRC(crc,&mMarkerOffset);
crc = AccumulateCRC(crc,(const char *)&mContentCount,sizeof(mContentCount));
crc = AccumulateCRC(crc,(const char *)&mIncrementCount,sizeof(mIncrementCount));
crc = AccumulateCRC(crc,(const char *)&mResetCount,sizeof(mResetCount));
crc = AccumulateCRC(crc,(const char *)&mQuotesCount,sizeof(mQuotesCount));
if (mContents) {
crc = AccumulateCRC(crc,(const char *)&(mContents->mType),sizeof(mContents->mType));
}
if (mIncrements) {
crc = AccumulateCRC(crc,(const char *)&(mIncrements->mValue),sizeof(mIncrements->mValue));
}
if (mResets) {
crc = AccumulateCRC(crc,(const char *)&(mResets->mValue),sizeof(mResets->mValue));
}
if (mQuotes) {
crc = StyleStringCRC(crc,mQuotes);
}
#endif
return crc;
}
//-----------------------
// nsStyleUserInterface
//
nsStyleUserInterface::nsStyleUserInterface(void) { }
struct StyleUserInterfaceImpl: public nsStyleUserInterface {
StyleUserInterfaceImpl(void) { }
void ResetFrom(const nsStyleUserInterface* aParent, nsIPresContext* aPresContext);
void SetFrom(const nsStyleUserInterface& aSource);
void CopyTo(nsStyleUserInterface& aDest) const;
PRInt32 CalcDifference(const StyleUserInterfaceImpl& aOther) const;
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
private: // These are not allowed
StyleUserInterfaceImpl(const StyleUserInterfaceImpl& aOther);
StyleUserInterfaceImpl& operator=(const StyleUserInterfaceImpl& aOther);
};
void StyleUserInterfaceImpl::ResetFrom(const nsStyleUserInterface* aParent, nsIPresContext* aPresContext)
{
if (aParent) {
mUserInput = aParent->mUserInput;
mUserModify = aParent->mUserModify;
mUserFocus = aParent->mUserFocus;
}
else {
mUserInput = NS_STYLE_USER_INPUT_AUTO;
mUserModify = NS_STYLE_USER_MODIFY_READ_ONLY;
mUserFocus = NS_STYLE_USER_FOCUS_NONE;
}
mUserSelect = NS_STYLE_USER_SELECT_AUTO;
mKeyEquivalent = PRUnichar(0); // XXX what type should this be?
mResizer = NS_STYLE_RESIZER_AUTO;
2000-04-16 00:15:37 +04:00
mBehavior.SetLength(0);
}
void StyleUserInterfaceImpl::SetFrom(const nsStyleUserInterface& aSource)
{
mUserInput = aSource.mUserInput;
mUserModify = aSource.mUserModify;
mUserFocus = aSource.mUserFocus;
mUserSelect = aSource.mUserSelect;
mKeyEquivalent = aSource.mKeyEquivalent;
mResizer = aSource.mResizer;
mBehavior = aSource.mBehavior;
}
void StyleUserInterfaceImpl::CopyTo(nsStyleUserInterface& aDest) const
{
aDest.mUserInput = mUserInput;
aDest.mUserModify = mUserModify;
aDest.mUserFocus = mUserFocus;
aDest.mUserSelect = mUserSelect;
aDest.mKeyEquivalent = mKeyEquivalent;
aDest.mResizer = mResizer;
aDest.mBehavior = mBehavior;
}
PRInt32 StyleUserInterfaceImpl::CalcDifference(const StyleUserInterfaceImpl& aOther) const
{
if (mBehavior != aOther.mBehavior)
return NS_STYLE_HINT_FRAMECHANGE;
if ((mUserInput == aOther.mUserInput) &&
(mResizer == aOther.mResizer)) {
if ((mUserModify == aOther.mUserModify) &&
(mUserSelect == aOther.mUserSelect)) {
if ((mKeyEquivalent == aOther.mKeyEquivalent) &&
(mUserFocus == aOther.mUserFocus) &&
(mResizer == aOther.mResizer)) {
return NS_STYLE_HINT_NONE;
}
return NS_STYLE_HINT_CONTENT;
}
return NS_STYLE_HINT_VISUAL;
}
if ((mUserInput != aOther.mUserInput) &&
((NS_STYLE_USER_INPUT_NONE == mUserInput) ||
(NS_STYLE_USER_INPUT_NONE == aOther.mUserInput))) {
return NS_STYLE_HINT_FRAMECHANGE;
}
return NS_STYLE_HINT_VISUAL;
}
PRUint32 StyleUserInterfaceImpl::ComputeCRC32(PRUint32 aCrc) const
{
PRUint32 crc = aCrc;
#ifdef COMPUTE_STYLEDATA_CRC
crc = AccumulateCRC(crc,(const char *)&mUserInput,sizeof(mUserInput));
crc = AccumulateCRC(crc,(const char *)&mUserModify,sizeof(mUserModify));
crc = AccumulateCRC(crc,(const char *)&mUserSelect,sizeof(mUserSelect));
crc = AccumulateCRC(crc,(const char *)&mUserFocus,sizeof(mUserFocus));
crc = AccumulateCRC(crc,(const char *)&mKeyEquivalent,sizeof(mKeyEquivalent));
crc = AccumulateCRC(crc,(const char *)&mResizer,sizeof(mResizer));
PRUint32 len;
len = mBehavior.Length();
crc = AccumulateCRC(crc,(const char *)&len,sizeof(len));
#endif
return crc;
}
//-----------------------
// nsStylePrint
//
nsStylePrint::nsStylePrint(void) { }
struct StylePrintImpl: public nsStylePrint {
StylePrintImpl(void) { }
void ResetFrom(const nsStylePrint* aParent, nsIPresContext* aPresContext);
void SetFrom(const nsStylePrint& aSource);
void CopyTo(nsStylePrint& aDest) const;
PRInt32 CalcDifference(const StylePrintImpl& aOther) const;
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
private: // These are not allowed
StylePrintImpl(const StylePrintImpl& aOther);
StylePrintImpl& operator=(const StylePrintImpl& aOther);
};
void StylePrintImpl::ResetFrom(const nsStylePrint* aParent, nsIPresContext* aPresContext)
{
if (aParent) {
mPageBreakBefore = aParent->mPageBreakBefore;
mPageBreakAfter = aParent->mPageBreakAfter;
mPageBreakInside = aParent->mPageBreakInside;
mWidows = aParent->mWidows;
mOrphans = aParent->mOrphans;
mMarks = aParent->mMarks;
mSizeWidth = aParent->mSizeWidth;
mSizeHeight = aParent->mSizeHeight;
}
else {
mPageBreakBefore = NS_STYLE_PAGE_BREAK_AUTO;
mPageBreakAfter = NS_STYLE_PAGE_BREAK_AUTO;
mPageBreakInside = NS_STYLE_PAGE_BREAK_AUTO;
mWidows = 2;
mOrphans = 2;
mMarks = NS_STYLE_PAGE_MARKS_NONE;
mSizeWidth.SetAutoValue();
mSizeHeight.SetAutoValue();
}
}
void StylePrintImpl::SetFrom(const nsStylePrint& aSource)
{
nsCRT::memcpy((nsStylePrint*)this, &aSource, sizeof(nsStylePrint));
}
void StylePrintImpl::CopyTo(nsStylePrint& aDest) const
{
nsCRT::memcpy(&aDest, (const nsStylePrint*)this, sizeof(nsStylePrint));
}
PRInt32 StylePrintImpl::CalcDifference(const StylePrintImpl& aOther) const
{
if ((mPageBreakBefore == aOther.mPageBreakBefore)
&& (mPageBreakAfter == aOther.mPageBreakAfter)
&& (mPageBreakInside == aOther.mPageBreakInside)
&& (mWidows == aOther.mWidows)
&& (mOrphans == aOther.mOrphans)
&& (mMarks == aOther.mMarks)
&& (mSizeWidth == aOther.mSizeWidth)
&& (mSizeHeight == aOther.mSizeHeight)) {
return NS_STYLE_HINT_NONE;
}
if (mMarks != aOther.mMarks) {
return NS_STYLE_HINT_VISUAL;
}
return NS_STYLE_HINT_REFLOW;
}
PRUint32 StylePrintImpl::ComputeCRC32(PRUint32 aCrc) const
{
PRUint32 crc = aCrc;
#ifdef COMPUTE_STYLEDATA_CRC
crc = AccumulateCRC(crc,(const char *)&mPageBreakBefore,sizeof(mPageBreakBefore));
crc = AccumulateCRC(crc,(const char *)&mPageBreakAfter,sizeof(mPageBreakAfter));
crc = AccumulateCRC(crc,(const char *)&mPageBreakInside,sizeof(mPageBreakInside));
PRUint32 len = mPage.Length();
crc = AccumulateCRC(crc,(const char *)&len,sizeof(len));
crc = AccumulateCRC(crc,(const char *)&mWidows,sizeof(mWidows));
crc = AccumulateCRC(crc,(const char *)&mOrphans,sizeof(mOrphans));
crc = AccumulateCRC(crc,(const char *)&mMarks,sizeof(mMarks));
crc = StyleCoordCRC(crc,&mSizeWidth);
crc = StyleCoordCRC(crc,&mSizeHeight);
#endif
return crc;
}
//----------------------------------------------------------------------
#ifdef SHARE_STYLECONTEXTS
class nsStyleContextData
{
public:
friend class StyleContextImpl;
void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize);
private: // all data and methods private: only friends have access
static nsStyleContextData *Create(nsIPresContext *aPresContext);
nsStyleContextData(nsIPresContext *aPresContext);
~nsStyleContextData(void);
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
void SetCRC32(void) { mCRC = ComputeCRC32(0); }
PRUint32 GetCRC32(void) const { return mCRC; }
PRUint32 AddRef(void);
PRUint32 Release(void);
// the style data...
// - StyleContextImpl gets friend-access
//
StyleFontImpl mFont;
StyleColorImpl mColor;
StyleSpacingImpl mSpacing;
StyleListImpl mList;
StylePositionImpl mPosition;
StyleTextImpl mText;
StyleDisplayImpl mDisplay;
StyleTableImpl mTable;
StyleContentImpl mContent;
StyleUserInterfaceImpl mUserInterface;
StylePrintImpl mPrint;
PRUint32 mRefCnt;
PRUint32 mCRC;
2000-10-28 06:46:30 +04:00
#ifdef DEBUG
static PRUint32 gInstanceCount;
#endif
};
#ifndef DEBUG
inline
#endif
PRUint32 nsStyleContextData::AddRef(void)
{
++mRefCnt;
NS_LOG_ADDREF(this,mRefCnt,"nsStyleContextData",sizeof(*this));
return mRefCnt;
}
#ifndef DEBUG
inline
#endif
PRUint32 nsStyleContextData::Release(void)
{
NS_ASSERTION(mRefCnt > 0, "RefCount error in nsStyleContextData");
--mRefCnt;
NS_LOG_RELEASE(this,mRefCnt,"nsStyleContextData");
if (0 == mRefCnt) {
#ifdef NOISY_DEBUG
printf("deleting nsStyleContextData instance: (%ld)\n", (long)(--gInstanceCount));
2000-10-28 06:46:30 +04:00
#endif
delete this;
return 0;
}
return mRefCnt;
}
2000-10-28 06:46:30 +04:00
#ifdef DEBUG
/*static*/ PRUint32 nsStyleContextData::gInstanceCount;
#endif // DEBUG
nsStyleContextData *nsStyleContextData::Create(nsIPresContext *aPresContext)
{
NS_ASSERTION(aPresContext != nsnull, "parameter cannot be null");
nsStyleContextData *pData = nsnull;
if (aPresContext) {
pData = new nsStyleContextData(aPresContext);
if (pData) {
NS_ADDREF(pData);
#ifdef NOISY_DEBUG
printf("new nsStyleContextData instance: (%ld) CRC=%lu\n",
(long)(++gInstanceCount), (unsigned long)pData->ComputeCRC32(0));
#endif // NOISY_DEBUG
}
}
return pData;
}
nsStyleContextData::nsStyleContextData(nsIPresContext *aPresContext)
: mFont(aPresContext->GetDefaultFontDeprecated(),
aPresContext->GetDefaultFixedFontDeprecated()),
mRefCnt(0), mCRC(0)
{
}
nsStyleContextData::~nsStyleContextData(void)
{
NS_ASSERTION(0 == mRefCnt, "RefCount error in ~nsStyleContextData");
// debug here...
}
PRUint32 nsStyleContextData::ComputeCRC32(PRUint32 aCrc) const
{
PRUint32 crc = aCrc;
#ifdef COMPUTE_STYLEDATA_CRC
// have each style struct compute its own CRC, propogating the previous value...
crc = mFont.ComputeCRC32(crc);
crc = mColor.ComputeCRC32(crc);
crc = mSpacing.ComputeCRC32(crc);
crc = mList.ComputeCRC32(crc);
crc = mPosition.ComputeCRC32(crc);
crc = mText.ComputeCRC32(crc);
crc = mDisplay.ComputeCRC32(crc);
crc = mTable.ComputeCRC32(crc);
crc = mContent.ComputeCRC32(crc);
crc = mUserInterface.ComputeCRC32(crc);
crc = mPrint.ComputeCRC32(crc);
#else
crc = 0;
#endif
return crc;
}
void nsStyleContextData::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize)
{
NS_ASSERTION(aSizeOfHandler, "SizeOfHandler cannot be null in SizeOf");
// first get the unique items collection
UNIQUE_STYLE_ITEMS(uniqueItems);
if(! uniqueItems->AddItem((void*)this) ){
// object has already been accounted for
return;
}
// get or create a tag for this instance
nsCOMPtr<nsIAtom> tag;
tag = getter_AddRefs(NS_NewAtom("StyleContextData"));
// get the size of an empty instance and add to the sizeof handler
aSize = sizeof(*this);
aSizeOfHandler->AddSize(tag,aSize);
}
#endif //#ifdef SHARE_STYLECONTEXTS
1998-04-14 00:24:54 +04:00
//----------------------------------------------------------------------
class StyleContextImpl : public nsIStyleContext,
protected nsIMutableStyleContext { // you can't QI to nsIMutableStyleContext
1998-04-14 00:24:54 +04:00
public:
StyleContextImpl(nsIStyleContext* aParent, nsIAtom* aPseudoTag,
nsISupportsArray* aRules,
nsIPresContext* aPresContext);
virtual ~StyleContextImpl();
1998-04-14 00:24:54 +04:00
1999-02-26 23:02:06 +03:00
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
1998-04-14 00:24:54 +04:00
NS_DECL_ISUPPORTS
virtual nsIStyleContext* GetParent(void) const;
virtual nsISupportsArray* GetStyleRules(void) const;
1998-05-21 00:32:57 +04:00
virtual PRInt32 GetStyleRuleCount(void) const;
NS_IMETHOD GetPseudoType(nsIAtom*& aPseudoTag) const;
1998-04-14 00:24:54 +04:00
NS_IMETHOD FindChildWithRules(const nsIAtom* aPseudoTag, nsISupportsArray* aRules,
nsIStyleContext*& aResult);
1998-04-14 00:24:54 +04:00
virtual PRBool Equals(const nsIStyleContext* aOther) const;
virtual PRUint32 HashValue(void) const;
NS_IMETHOD RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse = PR_TRUE);
NS_IMETHOD GetStyle(nsStyleStructID aSID, nsStyleStruct& aStruct) const;
NS_IMETHOD SetStyle(nsStyleStructID aSID, const nsStyleStruct& aStruct);
virtual const nsStyleStruct* GetStyleData(nsStyleStructID aSID);
virtual nsStyleStruct* GetMutableStyleData(nsStyleStructID aSID);
1998-04-14 00:24:54 +04:00
virtual void ForceUnique(void);
virtual void RecalcAutomaticData(nsIPresContext* aPresContext);
NS_IMETHOD CalcStyleDifference(nsIStyleContext* aOther, PRInt32& aHint,PRBool aStopAtFirstDifference = PR_FALSE) const;
#ifdef SHARE_STYLECONTEXTS
// evaluate and execute the style data sharing
// - if nothing to share, it leaves the current style data intact,
// otherwise it calls ShareStyleDataFrom to share another context's data
// and releases the old data
nsresult ShareStyleData(void);
// share the style data of the StyleDataDonor
// NOTE: the donor instance is cast to a StyleContextImpl to keep the
// interface free of implementation types. This may be invalid in
// the future
// XXX - reconfigure APIs to avoid casting the interface to the impl
nsresult ShareStyleDataFrom(nsIStyleContext*aStyleDataDonor);
// sets aMatches to PR_TRUE if the style data of aStyleContextToMatch matches the
// style data of this, PR_FALSE otherwise
NS_IMETHOD StyleDataMatches(nsIStyleContext* aStyleContextToMatch, PRBool *aMatches);
// get the key for this context (CRC32 value)
NS_IMETHOD GetStyleContextKey(scKey &aKey) const;
// update the style set cache by adding this context to it
// - NOTE: mStyleSet member must be set
nsresult UpdateStyleSetCache( void ) const;
#endif
1998-04-14 00:24:54 +04:00
1998-05-19 01:04:26 +04:00
virtual void List(FILE* out, PRInt32 aIndent);
virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize);
#ifdef DEBUG
virtual void DumpRegressionData(nsIPresContext* aPresContext, FILE* out, PRInt32 aIndent);
#endif
protected:
void AppendChild(StyleContextImpl* aChild);
1998-10-27 06:03:02 +03:00
void RemoveChild(StyleContextImpl* aChild);
StyleContextImpl* mParent;
StyleContextImpl* mChild;
StyleContextImpl* mEmptyChild;
StyleContextImpl* mPrevSibling;
StyleContextImpl* mNextSibling;
nsIAtom* mPseudoTag;
1998-10-08 05:27:38 +04:00
PRUint32 mRuleHash;
1998-04-14 00:24:54 +04:00
nsISupportsArray* mRules;
PRInt32 mDataCode;
1998-04-14 00:24:54 +04:00
#ifdef SHARE_STYLECONTEXTS
nsStyleContextData* mStyleData;
#else
1998-04-14 00:24:54 +04:00
// the style data...
StyleFontImpl mFont;
StyleColorImpl mColor;
StyleSpacingImpl mSpacing;
StyleListImpl mList;
StylePositionImpl mPosition;
StyleTextImpl mText;
StyleDisplayImpl mDisplay;
StyleTableImpl mTable;
StyleContentImpl mContent;
StyleUserInterfaceImpl mUserInterface;
StylePrintImpl mPrint;
#endif // #ifdef SHARE_STYLECONTEXTS
// make sure we have valid style data
nsresult EnsureStyleData(nsIPresContext* aPresContext);
nsresult HaveStyleData(void) const;
nsCOMPtr<nsIStyleSet> mStyleSet;
1998-04-14 00:24:54 +04:00
};
static PRInt32 gLastDataCode;
static PRBool HashStyleRule(nsISupports* aRule, void* aData)
1998-10-08 05:27:38 +04:00
{
*((PRUint32*)aData) ^= PRUint32(aRule);
return PR_TRUE;
}
StyleContextImpl::StyleContextImpl(nsIStyleContext* aParent,
nsIAtom* aPseudoTag,
nsISupportsArray* aRules,
1998-04-14 00:24:54 +04:00
nsIPresContext* aPresContext)
: mParent((StyleContextImpl*)aParent),
mChild(nsnull),
1998-10-08 05:27:38 +04:00
mEmptyChild(nsnull),
mPseudoTag(aPseudoTag),
1998-04-14 00:24:54 +04:00
mRules(aRules),
mDataCode(-1),
#ifdef SHARE_STYLECONTEXTS
mStyleData(nsnull)
#else
mFont(aPresContext->GetDefaultFontDeprecated(), aPresContext->GetDefaultFixedFontDeprecated()),
1998-04-14 00:24:54 +04:00
mColor(),
1998-04-21 04:02:44 +04:00
mSpacing(),
1998-04-14 00:24:54 +04:00
mList(),
mPosition(),
mText(),
mDisplay(),
mTable(),
mContent(),
mUserInterface(),
mPrint()
#endif
1998-04-14 00:24:54 +04:00
{
NS_INIT_REFCNT();
NS_IF_ADDREF(mPseudoTag);
1998-04-14 00:24:54 +04:00
NS_IF_ADDREF(mRules);
mNextSibling = this;
mPrevSibling = this;
if (nsnull != mParent) {
NS_ADDREF(mParent);
mParent->AppendChild(this);
1998-04-14 00:24:54 +04:00
}
1998-10-08 05:27:38 +04:00
mRuleHash = 0;
if (nsnull != mRules) {
mRules->EnumerateForwards(HashStyleRule, &mRuleHash);
}
#ifdef SHARE_STYLECONTEXTS
// remember the style set
nsIPresShell* shell = nsnull;
aPresContext->GetShell(&shell);
if (shell) {
shell->GetStyleSet( getter_AddRefs(mStyleSet) );
NS_RELEASE( shell );
}
#endif // SHARE_STYLECONTEXTS
1998-04-14 00:24:54 +04:00
}
StyleContextImpl::~StyleContextImpl()
{
NS_ASSERTION((nsnull == mChild) && (nsnull == mEmptyChild), "destructing context with children");
1999-04-02 22:48:55 +04:00
if (mParent) {
mParent->RemoveChild(this);
NS_RELEASE(mParent);
}
NS_IF_RELEASE(mPseudoTag);
1998-04-14 00:24:54 +04:00
NS_IF_RELEASE(mRules);
#ifdef SHARE_STYLECONTEXTS
// remove this instance from the style set (remember, the set does not AddRef or Release us)
if (mStyleSet) {
mStyleSet->RemoveStyleContext((nsIStyleContext *)this);
} else {
NS_ASSERTION(0, "StyleSet is not optional in a StyleContext's dtor...");
}
// release the style data so it can be reclaimed when no longer referenced
NS_IF_RELEASE(mStyleData);
#endif // SHARE_STYLECONTEXTS
1999-04-28 02:08:48 +04:00
}
NS_IMPL_ADDREF(StyleContextImpl)
NS_IMPL_RELEASE(StyleContextImpl)
NS_IMETHODIMP
StyleContextImpl::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
NS_PRECONDITION(nsnull != aInstancePtr, "null pointer");
if (nsnull == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
if (aIID.Equals(NS_GET_IID(nsIStyleContext))) {
*aInstancePtr = (void*)(nsIStyleContext*)this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*) (nsISupports*)(nsIStyleContext*)this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
1998-04-14 00:24:54 +04:00
nsIStyleContext* StyleContextImpl::GetParent(void) const
{
NS_IF_ADDREF(mParent);
return mParent;
}
void StyleContextImpl::AppendChild(StyleContextImpl* aChild)
{
if (0 == aChild->GetStyleRuleCount()) {
if (nsnull == mEmptyChild) {
mEmptyChild = aChild;
}
else {
aChild->mNextSibling = mEmptyChild;
aChild->mPrevSibling = mEmptyChild->mPrevSibling;
mEmptyChild->mPrevSibling->mNextSibling = aChild;
mEmptyChild->mPrevSibling = aChild;
}
}
else {
1998-10-08 05:27:38 +04:00
if (nsnull == mChild) {
mChild = aChild;
}
else {
aChild->mNextSibling = mChild;
aChild->mPrevSibling = mChild->mPrevSibling;
mChild->mPrevSibling->mNextSibling = aChild;
mChild->mPrevSibling = aChild;
}
}
}
1998-10-27 06:03:02 +03:00
void StyleContextImpl::RemoveChild(StyleContextImpl* aChild)
{
NS_ASSERTION((nsnull != aChild) && (this == aChild->mParent), "bad argument");
1998-10-27 06:03:02 +03:00
if ((nsnull == aChild) || (this != aChild->mParent)) {
1998-10-27 06:03:02 +03:00
return;
}
if (0 == aChild->GetStyleRuleCount()) { // is empty
if (aChild->mPrevSibling != aChild) { // has siblings
if (mEmptyChild == aChild) {
mEmptyChild = mEmptyChild->mNextSibling;
}
}
else {
NS_ASSERTION(mEmptyChild == aChild, "bad sibling pointers");
mEmptyChild = nsnull;
}
1998-10-27 06:03:02 +03:00
}
else { // isn't empty
if (aChild->mPrevSibling != aChild) { // has siblings
1998-10-27 06:03:02 +03:00
if (mChild == aChild) {
mChild = mChild->mNextSibling;
}
}
else {
NS_ASSERTION(mChild == aChild, "bad sibling pointers");
if (mChild == aChild) {
mChild = nsnull;
}
}
}
aChild->mPrevSibling->mNextSibling = aChild->mNextSibling;
aChild->mNextSibling->mPrevSibling = aChild->mPrevSibling;
aChild->mNextSibling = aChild;
aChild->mPrevSibling = aChild;
1998-10-27 06:03:02 +03:00
}
1998-04-14 00:24:54 +04:00
nsISupportsArray* StyleContextImpl::GetStyleRules(void) const
{
nsISupportsArray* result = mRules;
NS_IF_ADDREF(result);
return result;
1998-04-14 00:24:54 +04:00
}
1998-05-21 00:32:57 +04:00
PRInt32 StyleContextImpl::GetStyleRuleCount(void) const
{
if (nsnull != mRules) {
PRUint32 cnt;
nsresult rv = mRules->Count(&cnt);
if (NS_FAILED(rv)) return 0; // XXX error?
return cnt;
1998-05-21 00:32:57 +04:00
}
return 0;
}
NS_IMETHODIMP
StyleContextImpl::GetPseudoType(nsIAtom*& aPseudoTag) const
{
aPseudoTag = mPseudoTag;
NS_IF_ADDREF(aPseudoTag);
return NS_OK;
}
NS_IMETHODIMP
StyleContextImpl::FindChildWithRules(const nsIAtom* aPseudoTag,
nsISupportsArray* aRules,
nsIStyleContext*& aResult)
{
aResult = nsnull;
1998-10-08 05:27:38 +04:00
if ((nsnull != mChild) || (nsnull != mEmptyChild)) {
StyleContextImpl* child;
PRInt32 ruleCount;
if (aRules) {
PRUint32 cnt;
nsresult rv = aRules->Count(&cnt);
if (NS_FAILED(rv)) return rv;
ruleCount = cnt;
}
else
ruleCount = 0;
1998-10-08 05:27:38 +04:00
if (0 == ruleCount) {
if (nsnull != mEmptyChild) {
child = mEmptyChild;
do {
if ((0 == child->mDataCode) && // only look at children with un-twiddled data
(aPseudoTag == child->mPseudoTag)) {
aResult = child;
break;
}
child = child->mNextSibling;
} while (child != mEmptyChild);
}
1998-10-08 05:27:38 +04:00
}
else if (nsnull != mChild) {
PRUint32 hash = 0;
aRules->EnumerateForwards(HashStyleRule, &hash);
child = mChild;
1998-10-08 05:27:38 +04:00
do {
PRUint32 cnt;
1998-10-08 05:27:38 +04:00
if ((0 == child->mDataCode) && // only look at children with un-twiddled data
(child->mRuleHash == hash) &&
(child->mPseudoTag == aPseudoTag) &&
(nsnull != child->mRules) &&
NS_SUCCEEDED(child->mRules->Count(&cnt)) &&
(PRInt32)cnt == ruleCount) {
1998-10-08 05:27:38 +04:00
if (child->mRules->Equals(aRules)) {
aResult = child;
1998-10-08 05:27:38 +04:00
break;
}
}
1998-10-08 05:27:38 +04:00
child = child->mNextSibling;
} while (child != mChild);
}
}
NS_IF_ADDREF(aResult);
return NS_OK;
}
1998-04-14 00:24:54 +04:00
PRBool StyleContextImpl::Equals(const nsIStyleContext* aOther) const
{
PRBool result = PR_TRUE;
const StyleContextImpl* other = (StyleContextImpl*)aOther;
if (other != this) {
if (mParent != other->mParent) {
result = PR_FALSE;
}
else if (mDataCode != other->mDataCode) {
result = PR_FALSE;
}
else if (mPseudoTag != other->mPseudoTag) {
result = PR_FALSE;
}
1998-04-14 00:24:54 +04:00
else {
if ((nsnull != mRules) && (nsnull != other->mRules)) {
if (mRuleHash == other->mRuleHash) {
result = mRules->Equals(other->mRules);
}
else {
result = PR_FALSE;
}
1998-04-14 00:24:54 +04:00
}
else {
result = PRBool((nsnull == mRules) && (nsnull == other->mRules));
}
}
}
return result;
}
PRUint32 StyleContextImpl::HashValue(void) const
{
1998-10-08 05:27:38 +04:00
return mRuleHash;
1998-04-14 00:24:54 +04:00
}
const nsStyleStruct* StyleContextImpl::GetStyleData(nsStyleStructID aSID)
1998-04-14 00:24:54 +04:00
{
nsStyleStruct* result = nsnull;
switch (aSID) {
case eStyleStruct_Font:
result = & GETSCDATA(Font);
break;
case eStyleStruct_Color:
result = & GETSCDATA(Color);
break;
case eStyleStruct_Spacing:
result = & GETSCDATA(Spacing);
break;
case eStyleStruct_List:
result = & GETSCDATA(List);
break;
case eStyleStruct_Position:
result = & GETSCDATA(Position);
break;
case eStyleStruct_Text:
result = & GETSCDATA(Text);
break;
case eStyleStruct_Display:
result = & GETSCDATA(Display);
break;
case eStyleStruct_Table:
result = & GETSCDATA(Table);
break;
case eStyleStruct_Content:
result = & GETSCDATA(Content);
break;
case eStyleStruct_UserInterface:
result = & GETSCDATA(UserInterface);
1999-04-02 22:48:55 +04:00
break;
case eStyleStruct_Print:
result = & GETSCDATA(Print);
break;
default:
NS_ERROR("Invalid style struct id");
break;
}
return result;
1998-04-14 00:24:54 +04:00
}
nsStyleStruct* StyleContextImpl::GetMutableStyleData(nsStyleStructID aSID)
{
nsStyleStruct* result = nsnull;
switch (aSID) {
case eStyleStruct_Font:
result = & GETSCDATA(Font);
break;
case eStyleStruct_Color:
result = & GETSCDATA(Color);
break;
case eStyleStruct_Spacing:
result = & GETSCDATA(Spacing);
break;
case eStyleStruct_List:
result = & GETSCDATA(List);
break;
case eStyleStruct_Position:
result = & GETSCDATA(Position);
break;
case eStyleStruct_Text:
result = & GETSCDATA(Text);
break;
case eStyleStruct_Display:
result = & GETSCDATA(Display);
break;
case eStyleStruct_Table:
result = & GETSCDATA(Table);
break;
case eStyleStruct_Content:
result = & GETSCDATA(Content);
break;
case eStyleStruct_UserInterface:
result = & GETSCDATA(UserInterface);
1999-04-02 22:48:55 +04:00
break;
case eStyleStruct_Print:
result = & GETSCDATA(Print);
break;
default:
NS_ERROR("Invalid style struct id");
break;
}
if (nsnull != result) {
if (0 == mDataCode) {
// mDataCode = ++gLastDataCode; // XXX temp disable, this is still used but not needed to force unique
}
}
return result;
}
NS_IMETHODIMP
StyleContextImpl::GetStyle(nsStyleStructID aSID, nsStyleStruct& aStruct) const
{
nsresult result = NS_OK;
switch (aSID) {
case eStyleStruct_Font:
GETSCDATA(Font).CopyTo((nsStyleFont&)aStruct);
break;
case eStyleStruct_Color:
GETSCDATA(Color).CopyTo((nsStyleColor&)aStruct);
break;
case eStyleStruct_Spacing:
GETSCDATA(Spacing).CopyTo((nsStyleSpacing&)aStruct);
break;
case eStyleStruct_List:
GETSCDATA(List).CopyTo((nsStyleList&)aStruct);
break;
case eStyleStruct_Position:
GETSCDATA(Position).CopyTo((nsStylePosition&)aStruct);
break;
case eStyleStruct_Text:
GETSCDATA(Text).CopyTo((nsStyleText&)aStruct);
break;
case eStyleStruct_Display:
GETSCDATA(Display).CopyTo((nsStyleDisplay&)aStruct);
break;
case eStyleStruct_Table:
GETSCDATA(Table).CopyTo((nsStyleTable&)aStruct);
break;
case eStyleStruct_Content:
GETSCDATA(Content).CopyTo((nsStyleContent&)aStruct);
break;
case eStyleStruct_UserInterface:
GETSCDATA(UserInterface).CopyTo((nsStyleUserInterface&)aStruct);
break;
case eStyleStruct_Print:
GETSCDATA(Print).CopyTo((nsStylePrint&)aStruct);
break;
default:
NS_ERROR("Invalid style struct id");
result = NS_ERROR_INVALID_ARG;
break;
}
return result;
}
NS_IMETHODIMP
StyleContextImpl::SetStyle(nsStyleStructID aSID, const nsStyleStruct& aStruct)
{
nsresult result = NS_OK;
switch (aSID) {
case eStyleStruct_Font:
GETSCDATA(Font).SetFrom((const nsStyleFont&)aStruct);
break;
case eStyleStruct_Color:
GETSCDATA(Color).SetFrom((const nsStyleColor&)aStruct);
break;
case eStyleStruct_Spacing:
GETSCDATA(Spacing).SetFrom((const nsStyleSpacing&)aStruct);
break;
case eStyleStruct_List:
GETSCDATA(List).SetFrom((const nsStyleList&)aStruct);
break;
case eStyleStruct_Position:
GETSCDATA(Position).SetFrom((const nsStylePosition&)aStruct);
break;
case eStyleStruct_Text:
GETSCDATA(Text).SetFrom((const nsStyleText&)aStruct);
break;
case eStyleStruct_Display:
GETSCDATA(Display).SetFrom((const nsStyleDisplay&)aStruct);
break;
case eStyleStruct_Table:
GETSCDATA(Table).SetFrom((const nsStyleTable&)aStruct);
break;
case eStyleStruct_Content:
GETSCDATA(Content).SetFrom((const nsStyleContent&)aStruct);
break;
case eStyleStruct_UserInterface:
GETSCDATA(UserInterface).SetFrom((const nsStyleUserInterface&)aStruct);
break;
case eStyleStruct_Print:
GETSCDATA(Print).SetFrom((const nsStylePrint&)aStruct);
break;
default:
NS_ERROR("Invalid style struct id");
result = NS_ERROR_INVALID_ARG;
break;
}
return result;
}
struct MapStyleData {
MapStyleData(nsIMutableStyleContext* aStyleContext, nsIPresContext* aPresContext)
{
mStyleContext = aStyleContext;
mPresContext = aPresContext;
}
nsIMutableStyleContext* mStyleContext;
nsIPresContext* mPresContext;
};
static PRBool MapStyleRuleFont(nsISupports* aRule, void* aData)
{
nsIStyleRule* rule = (nsIStyleRule*)aRule;
MapStyleData* data = (MapStyleData*)aData;
rule->MapFontStyleInto(data->mStyleContext, data->mPresContext);
return PR_TRUE;
}
static PRBool MapStyleRule(nsISupports* aRule, void* aData)
{
nsIStyleRule* rule = (nsIStyleRule*)aRule;
MapStyleData* data = (MapStyleData*)aData;
1998-09-05 07:52:30 +04:00
rule->MapStyleInto(data->mStyleContext, data->mPresContext);
return PR_TRUE;
}
1998-09-25 03:56:30 +04:00
NS_IMETHODIMP
StyleContextImpl::RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse)
1998-04-14 00:24:54 +04:00
{
mDataCode = -1;
if (NS_FAILED(EnsureStyleData(aPresContext))) {
return NS_ERROR_UNEXPECTED;
}
if (nsnull != mParent) {
GETSCDATA(Font).ResetFrom(&(mParent->GETSCDATA(Font)), aPresContext);
GETSCDATA(Color).ResetFrom(&(mParent->GETSCDATA(Color)), aPresContext);
GETSCDATA(Spacing).ResetFrom(&(mParent->GETSCDATA(Spacing)), aPresContext);
GETSCDATA(List).ResetFrom(&(mParent->GETSCDATA(List)), aPresContext);
GETSCDATA(Position).ResetFrom(&(mParent->GETSCDATA(Position)), aPresContext);
GETSCDATA(Text).ResetFrom(&(mParent->GETSCDATA(Text)), aPresContext);
GETSCDATA(Display).ResetFrom(&(mParent->GETSCDATA(Display)), aPresContext);
GETSCDATA(Table).ResetFrom(&(mParent->GETSCDATA(Table)), aPresContext);
GETSCDATA(Content).ResetFrom(&(mParent->GETSCDATA(Content)), aPresContext);
GETSCDATA(UserInterface).ResetFrom(&(mParent->GETSCDATA(UserInterface)), aPresContext);
GETSCDATA(Print).ResetFrom(&(mParent->GETSCDATA(Print)), aPresContext);
}
else {
GETSCDATA(Font).ResetFrom(nsnull, aPresContext);
GETSCDATA(Color).ResetFrom(nsnull, aPresContext);
GETSCDATA(Spacing).ResetFrom(nsnull, aPresContext);
GETSCDATA(List).ResetFrom(nsnull, aPresContext);
GETSCDATA(Position).ResetFrom(nsnull, aPresContext);
GETSCDATA(Text).ResetFrom(nsnull, aPresContext);
GETSCDATA(Display).ResetFrom(nsnull, aPresContext);
GETSCDATA(Table).ResetFrom(nsnull, aPresContext);
GETSCDATA(Content).ResetFrom(nsnull, aPresContext);
GETSCDATA(UserInterface).ResetFrom(nsnull, aPresContext);
GETSCDATA(Print).ResetFrom(nsnull, aPresContext);
}
PRUint32 cnt = 0;
if (mRules) {
nsresult rv = mRules->Count(&cnt);
NS_ASSERTION(NS_SUCCEEDED(rv), "Count failed");
}
if (0 < cnt) {
1998-09-05 07:52:30 +04:00
MapStyleData data(this, aPresContext);
mRules->EnumerateForwards(MapStyleRuleFont, &data);
if (GETSCDATA(Font).mFlags & NS_STYLE_FONT_USE_FIXED) {
GETSCDATA(Font).mFont = GETSCDATA(Font).mFixedFont;
1999-07-07 05:22:04 +04:00
}
mRules->EnumerateForwards(MapStyleRule, &data);
}
if (-1 == mDataCode) {
mDataCode = 0;
}
// CSS2 specified fixups:
// - these must be done after all declarations are mapped since they can cross style-structs
// 1) if float is not none, and display is not none, then we must set display to block
// XXX - there are problems with following the spec here: what we will do instead of
// following the letter of the spec is to make sure that floated elements are
// some kind of block, not strictly 'block' - see EnsureBlockDisplay method
nsStyleDisplay *disp = (nsStyleDisplay *)GetMutableStyleData(eStyleStruct_Display);
if (disp) {
if (disp->mDisplay != NS_STYLE_DISPLAY_NONE &&
disp->mFloats != NS_STYLE_FLOAT_NONE ) {
EnsureBlockDisplay(disp->mDisplay);
}
}
// 2) if position is 'absolute' or 'fixed' then display must be 'block and float must be 'none'
// XXX - see note for fixup 1) above...
nsStylePosition *pos = (nsStylePosition *)GetStyleData(eStyleStruct_Position);
if (pos) {
if (pos->IsAbsolutelyPositioned()) {
if (disp) {
if(disp->mDisplay != NS_STYLE_DISPLAY_NONE) {
EnsureBlockDisplay(disp->mDisplay);
disp->mFloats = NS_STYLE_FLOAT_NONE;
}
}
}
}
nsCompatibility quirkMode = eCompatibility_Standard;
aPresContext->GetCompatibilityMode(&quirkMode);
if (eCompatibility_NavQuirks == quirkMode) {
if (((GETSCDATA(Display).mDisplay == NS_STYLE_DISPLAY_TABLE) ||
(GETSCDATA(Display).mDisplay == NS_STYLE_DISPLAY_TABLE_CAPTION)) &&
2000-09-06 06:34:35 +04:00
(nsnull == mPseudoTag)) {
StyleContextImpl* holdParent = mParent;
mParent = nsnull; // cut off all inheritance. this really blows
// XXX the style we do preserve is visibility, direction, language
PRUint8 visible = GETSCDATA(Display).mVisible;
PRUint8 direction = GETSCDATA(Display).mDirection;
nsCOMPtr<nsILanguageAtom> language = GETSCDATA(Display).mLanguage;
// time to emulate a sub-document
// This is ugly, but we need to map style once to determine display type
// then reset and map it again so that all local style is preserved
if (GETSCDATA(Display).mDisplay != NS_STYLE_DISPLAY_TABLE) {
GETSCDATA(Font).ResetFrom(nsnull, aPresContext);
}
GETSCDATA(Color).ResetFrom(nsnull, aPresContext);
GETSCDATA(Spacing).ResetFrom(nsnull, aPresContext);
GETSCDATA(List).ResetFrom(nsnull, aPresContext);
GETSCDATA(Text).ResetFrom(nsnull, aPresContext);
GETSCDATA(Position).ResetFrom(nsnull, aPresContext);
GETSCDATA(Display).ResetFrom(nsnull, aPresContext);
GETSCDATA(Table).ResetFrom(nsnull, aPresContext);
GETSCDATA(Content).ResetFrom(nsnull, aPresContext);
GETSCDATA(UserInterface).ResetFrom(nsnull, aPresContext);
GETSCDATA(Print).ResetFrom(nsnull, aPresContext);
GETSCDATA(Display).mVisible = visible;
GETSCDATA(Display).mDirection = direction;
GETSCDATA(Display).mLanguage = language;
PRUint32 numRules = 0;
if (mRules) {
nsresult rv = mRules->Count(&numRules);
NS_ASSERTION(NS_SUCCEEDED(rv), "Count failed");
}
if (0 < numRules) {
MapStyleData data(this, aPresContext);
mRules->EnumerateForwards(MapStyleRuleFont, &data);
if (GETSCDATA(Font).mFlags & NS_STYLE_FONT_USE_FIXED) {
GETSCDATA(Font).mFont = GETSCDATA(Font).mFixedFont;
1999-07-07 05:22:04 +04:00
}
mRules->EnumerateForwards(MapStyleRule, &data);
}
// reset all font data for tables again
if (GETSCDATA(Display).mDisplay == NS_STYLE_DISPLAY_TABLE) {
// get the font-name to reset: this property we preserve
nsAutoString strName(GETSCDATA(Font).mFont.name);
nsAutoString strMixedName(GETSCDATA(Font).mFixedFont.name);
GETSCDATA(Font).ResetFrom(nsnull, aPresContext);
// now reset the font names back to original
GETSCDATA(Font).mFont.name = strName;
GETSCDATA(Font).mFixedFont.name = strMixedName;
}
mParent = holdParent;
}
} else {
// In strict mode, we still have to support one "quirky" thing
// for tables. HTML's alignment attributes have always worked
// so they don't inherit into tables, but instead align the
// tables. We should keep doing this, because HTML alignment
// is just weird, and we shouldn't force it to match CSS.
if (GETSCDATA(Display).mDisplay == NS_STYLE_DISPLAY_TABLE) {
// -moz-center and -moz-right are used for HTML's alignment
if ((GETSCDATA(Text).mTextAlign == NS_STYLE_TEXT_ALIGN_MOZ_CENTER) ||
(GETSCDATA(Text).mTextAlign == NS_STYLE_TEXT_ALIGN_MOZ_RIGHT))
{
GETSCDATA(Text).mTextAlign = NS_STYLE_TEXT_ALIGN_DEFAULT;
}
}
}
1998-10-27 06:03:02 +03:00
RecalcAutomaticData(aPresContext);
#ifdef SHARE_STYLECONTEXTS
nsresult result = ShareStyleData();
#endif
if (aRecurse) {
if (nsnull != mChild) {
StyleContextImpl* child = mChild;
do {
child->RemapStyle(aPresContext);
child = child->mNextSibling;
} while (mChild != child);
}
if (nsnull != mEmptyChild) {
StyleContextImpl* child = mEmptyChild;
do {
child->RemapStyle(aPresContext);
child = child->mNextSibling;
} while (mEmptyChild != child);
}
1998-10-27 06:03:02 +03:00
}
1998-09-25 03:56:30 +04:00
return NS_OK;
}
void StyleContextImpl::ForceUnique(void)
{
if (mDataCode <= 0) {
mDataCode = ++gLastDataCode;
}
1998-04-14 00:24:54 +04:00
}
void StyleContextImpl::RecalcAutomaticData(nsIPresContext* aPresContext)
1998-04-21 04:02:44 +04:00
{
if (NS_FAILED(EnsureStyleData(aPresContext))) {
return /*NS_FAILURE*/;
}
GETSCDATA(Spacing).RecalcData(aPresContext, GETSCDATA(Color).mColor);
1999-02-27 10:11:42 +03:00
}
1999-02-27 10:11:42 +03:00
NS_IMETHODIMP
StyleContextImpl::CalcStyleDifference(nsIStyleContext* aOther, PRInt32& aHint,PRBool aStopAtFirstDifference /*= PR_FALSE*/) const
1999-02-27 10:11:42 +03:00
{
if (NS_FAILED(HaveStyleData())) {
return NS_ERROR_NULL_POINTER;
}
1999-02-27 10:11:42 +03:00
if (aOther) {
PRInt32 hint;
const StyleContextImpl* other = (const StyleContextImpl*)aOther;
aHint = GETSCDATA(Font).CalcDifference(other->GETSCDATA(Font));
if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK;
1999-02-27 10:11:42 +03:00
if (aHint < NS_STYLE_HINT_MAX) {
hint = GETSCDATA(Color).CalcDifference(other->GETSCDATA(Color));
1999-02-27 10:11:42 +03:00
if (aHint < hint) {
aHint = hint;
}
}
if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK;
1999-02-27 10:11:42 +03:00
if (aHint < NS_STYLE_HINT_MAX) {
hint = GETSCDATA(Spacing).CalcDifference(other->GETSCDATA(Spacing));
1999-02-27 10:11:42 +03:00
if (aHint < hint) {
aHint = hint;
}
}
if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK;
1999-02-27 10:11:42 +03:00
if (aHint < NS_STYLE_HINT_MAX) {
hint = GETSCDATA(List).CalcDifference(other->GETSCDATA(List));
1999-02-27 10:11:42 +03:00
if (aHint < hint) {
aHint = hint;
}
}
if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK;
1999-02-27 10:11:42 +03:00
if (aHint < NS_STYLE_HINT_MAX) {
hint = GETSCDATA(Position).CalcDifference(other->GETSCDATA(Position));
1999-02-27 10:11:42 +03:00
if (aHint < hint) {
aHint = hint;
}
}
if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK;
1999-02-27 10:11:42 +03:00
if (aHint < NS_STYLE_HINT_MAX) {
hint = GETSCDATA(Text).CalcDifference(other->GETSCDATA(Text));
1999-02-27 10:11:42 +03:00
if (aHint < hint) {
aHint = hint;
}
}
if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK;
1999-02-27 10:11:42 +03:00
if (aHint < NS_STYLE_HINT_MAX) {
hint = GETSCDATA(Display).CalcDifference(other->GETSCDATA(Display));
1999-02-27 10:11:42 +03:00
if (aHint < hint) {
aHint = hint;
}
}
if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK;
1999-02-27 10:11:42 +03:00
if (aHint < NS_STYLE_HINT_MAX) {
hint = GETSCDATA(Table).CalcDifference(other->GETSCDATA(Table));
1999-02-27 10:11:42 +03:00
if (aHint < hint) {
aHint = hint;
}
}
if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK;
1999-04-02 22:48:55 +04:00
if (aHint < NS_STYLE_HINT_MAX) {
hint = GETSCDATA(Content).CalcDifference(other->GETSCDATA(Content));
if (aHint < hint) {
aHint = hint;
1999-04-02 22:48:55 +04:00
}
}
if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK;
if (aHint < NS_STYLE_HINT_MAX) {
hint = GETSCDATA(UserInterface).CalcDifference(other->GETSCDATA(UserInterface));
1999-04-02 22:48:55 +04:00
if (aHint < hint) {
aHint = hint;
}
}
if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK;
if (aHint < NS_STYLE_HINT_MAX) {
hint = GETSCDATA(Print).CalcDifference(other->GETSCDATA(Print));
if (aHint < hint) {
aHint = hint;
}
}
1999-02-27 10:11:42 +03:00
}
return NS_OK;
1998-04-14 00:24:54 +04:00
}
1999-02-27 10:11:42 +03:00
nsresult StyleContextImpl::EnsureStyleData(nsIPresContext* aPresContext)
{
nsresult rv = NS_OK;
NS_ASSERTION(aPresContext, "null presContext argument is illegal and immoral");
if (nsnull == aPresContext) {
// no pres context provided, and we have no style data, so send back an error
return NS_ERROR_FAILURE;
}
#ifdef SHARE_STYLECONTEXTS
// See if we already have data...
if (NS_FAILED(HaveStyleData())) {
// we were provided a pres context so create a new style data
mStyleData = nsStyleContextData::Create(aPresContext);
if (nsnull == mStyleData) {
rv = NS_ERROR_OUT_OF_MEMORY;
}
} else {
// already have style data - OK!
rv = NS_OK;
}
#endif //#ifdef SHARE_STYLECONTEXTS
return rv;
}
nsresult StyleContextImpl::HaveStyleData(void) const
{
#ifdef SHARE_STYLECONTEXTS
return (nsnull == mStyleData) ? NS_ERROR_NULL_POINTER : NS_OK;
#else
return NS_OK;
#endif
}
#ifdef SHARE_STYLECONTEXTS
nsresult StyleContextImpl::ShareStyleData(void)
{
nsresult result = NS_OK;
// Enable flag: this is TRUE by default, however the env. var. moz_disable_style_sharing
// can be set to '1' to disable the sharing before the app is launched
static char *disableSharing = PR_GetEnv("moz_disable_style_sharing");
static PRBool bEnableSharing = (disableSharing == nsnull) ||
(*disableSharing != '1');
#ifdef DEBUG
static PRBool bOnce = PR_FALSE;
if(!bOnce){
printf( "Style Data Sharing is %s\n", bEnableSharing ? "Enabled :)" : "Disabled :(" );
bOnce = PR_TRUE;
}
#endif
PRBool bSharingSupported = PR_TRUE;
if (bEnableSharing) {
// NOTE: sharing of style data for the GfxScrollFrame is problematic
// and is currently disabled. These pseudos indicate the use of a GfxScrollFrame
// so we check for them and disallow sharing when any are found.
// If you haen;t guessed it, this is a total hack until we can figure out
// why the GfxScrollFrame is not happy having its style data shared...
// (See bugzilla bug 39618 which also documents this problem)
if(mPseudoTag) {
if(mPseudoTag == nsLayoutAtoms::viewportPseudo ||
mPseudoTag == nsLayoutAtoms::canvasPseudo ||
mPseudoTag == nsLayoutAtoms::viewportScrollPseudo ||
mPseudoTag == nsLayoutAtoms::scrolledContentPseudo ||
mPseudoTag == nsLayoutAtoms::selectScrolledContentPseudo) {
bSharingSupported = PR_FALSE;
} else {
bSharingSupported = PR_TRUE;
}
}
}
if (bEnableSharing && bSharingSupported) {
// set the CRC
mStyleData->SetCRC32();
NS_ASSERTION(mStyleSet, "Expected to have a style set ref...");
nsIStyleContext *matchingSC = nsnull;
// check if there is a matching context...
result = mStyleSet->FindMatchingContext(this, &matchingSC);
if ((NS_SUCCEEDED(result)) &&
(nsnull != matchingSC)) {
ShareStyleDataFrom(matchingSC);
#ifdef NOISY_DEBUG
printf("SC Data Shared :)\n");
#endif
NS_IF_RELEASE(matchingSC);
} else {
#ifdef NOISY_DEBUG
printf("Unique SC Data - Not Shared :(\n");
#endif
}
}
return result;
}
nsresult StyleContextImpl::ShareStyleDataFrom(nsIStyleContext*aStyleDataDonor)
{
nsresult rv = NS_OK;
if (aStyleDataDonor) {
// XXX - static cast is nasty, especially if there are multiple
// nsIStyleContext implementors...
StyleContextImpl *donor = NS_STATIC_CAST(StyleContextImpl*,aStyleDataDonor);
// get the data from the donor
nsStyleContextData *pData = donor->mStyleData;
if (pData != nsnull) {
NS_ADDREF(pData);
NS_IF_RELEASE(mStyleData);
mStyleData = pData;
}
}
return rv;
}
#ifdef DEBUG
long gFalsePos=0;
long gScreenedByCRC=0;
#endif
NS_IMETHODIMP
StyleContextImpl::StyleDataMatches(nsIStyleContext* aStyleContextToMatch,
PRBool *aMatches)
{
NS_ASSERTION((aStyleContextToMatch != nsnull) &&
(aStyleContextToMatch != this) &&
(aMatches != nsnull), "invalid parameter");
nsresult rv = NS_OK;
// XXX - static cast is nasty, especially if there are multiple
// nsIStyleContext implementors...
StyleContextImpl* other = NS_STATIC_CAST(StyleContextImpl*,aStyleContextToMatch);
*aMatches = PR_FALSE;
// check same pointer value
if (other->mStyleData != mStyleData) {
// check using the crc first:
// this will get past the vast majority which do not match,
// and if it does match then we'll double check with the more complete comparison
if (other->mStyleData->GetCRC32() == mStyleData->GetCRC32()) {
// Might match: validate using the more comprehensive (and slower) CalcStyleDifference
PRInt32 hint = 0;
CalcStyleDifference(aStyleContextToMatch, hint, PR_TRUE);
#ifdef DEBUG
if (hint > 0) {
gFalsePos++;
// printf("CRC match but CalcStyleDifference shows differences: crc is not sufficient?");
}
#endif
*aMatches = (0 == hint) ? PR_TRUE : PR_FALSE;
}
#ifdef DEBUG
else
{
// in DEBUG we make sure we are not missing any by getting false-negatives on the CRC
// XXX NOTE: this should be removed when we trust the CRC matching
// as this slows it way down
gScreenedByCRC++;
/*
PRInt32 hint = 0;
CalcStyleDifference(aStyleContextToMatch, hint, PR_TRUE);
NS_ASSERTION(hint>0,"!!!FALSE-NEGATIVE in StyleMatchesData!!!");
*/
}
// printf("False-Pos: %ld - Screened: %ld\n", gFalsePos, gScreenedByCRC);
#endif
}
return rv;
}
NS_IMETHODIMP StyleContextImpl::GetStyleContextKey(scKey &aKey) const
{
aKey = mStyleData->GetCRC32();
return NS_OK;
}
nsresult StyleContextImpl::UpdateStyleSetCache( void ) const
{
if (mStyleSet) {
// add it to the set: the set does NOT addref or release
return mStyleSet->AddStyleContext((nsIStyleContext *)this);
} else {
return NS_ERROR_FAILURE;
}
}
#endif
1998-05-19 01:04:26 +04:00
void StyleContextImpl::List(FILE* out, PRInt32 aIndent)
{
// Indent
PRInt32 ix;
for (ix = aIndent; --ix >= 0; ) fputs(" ", out);
1999-04-28 02:08:48 +04:00
fprintf(out, "%p(%d) ", this, mRefCnt);
if (nsnull != mPseudoTag) {
nsAutoString buffer;
mPseudoTag->ToString(buffer);
fputs(buffer, out);
fputs(" ", out);
}
PRInt32 count = GetStyleRuleCount();
1998-05-19 01:04:26 +04:00
if (0 < count) {
fputs("{\n", out);
for (ix = 0; ix < count; ix++) {
nsIStyleRule* rule = (nsIStyleRule*)mRules->ElementAt(ix);
1998-05-19 01:04:26 +04:00
rule->List(out, aIndent + 1);
NS_RELEASE(rule);
}
for (ix = aIndent; --ix >= 0; ) fputs(" ", out);
1998-05-19 01:04:26 +04:00
fputs("}\n", out);
}
else {
fputs("{}\n", out);
}
1998-06-26 09:49:01 +04:00
if (nsnull != mChild) {
StyleContextImpl* child = mChild;
do {
child->List(out, aIndent + 1);
child = child->mNextSibling;
1998-06-26 09:49:01 +04:00
} while (mChild != child);
}
1998-10-08 05:27:38 +04:00
if (nsnull != mEmptyChild) {
StyleContextImpl* child = mEmptyChild;
do {
child->List(out, aIndent + 1);
child = child->mNextSibling;
} while (mEmptyChild != child);
1998-10-08 05:27:38 +04:00
}
1998-05-19 01:04:26 +04:00
}
/******************************************************************************
* SizeOf method:
*
* Self (reported as StyleContextImpl's size):
* 1) sizeof(*this) which gets all of the data members
* 2) adds in the size of the PseudoTag, if there is one
*
* Contained / Aggregated data (not reported as StyleContextImpl's size):
* 1) the Style Rules in mRules are not counted as part of sizeof(*this)
* (though the size of the nsISupportsArray ptr. is) so we need to
* count the rules seperately. For each rule in the mRules collection
* we call the SizeOf method and let it report itself.
*
* Children / siblings / parents:
* 1) We recurse over the mChild and mEmptyChild instances if they exist.
* These instances will then be accumulated seperately (not part of
* the containing instance's size)
* 2) We recurse over the siblings of the Child and Empty Child instances
* and count then seperately as well.
* 3) We recurse over our direct siblings (if any).
*
******************************************************************************/
void StyleContextImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize)
{
NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null");
static PRBool bDetailDumpDone = PR_FALSE;
if (!bDetailDumpDone) {
bDetailDumpDone = PR_TRUE;
PRUint32 totalSize=0;
printf( "Detailed StyleContextImpl dump: basic class sizes of members\n" );
printf( "*************************************\n");
printf( " - StyleFontImpl: %ld\n", (long)sizeof(GETSCDATA(Font)) );
totalSize += (long)sizeof(GETSCDATA(Font));
printf( " - StyleColorImpl: %ld\n", (long)sizeof(GETSCDATA(Color)) );
totalSize += (long)sizeof(GETSCDATA(Color));
printf( " - StyleSpacingImpl: %ld\n", (long)sizeof(GETSCDATA(Spacing)) );
totalSize += (long)sizeof(GETSCDATA(Spacing));
printf( " - StyleListImpl: %ld\n", (long)sizeof(GETSCDATA(List)) );
totalSize += (long)sizeof(GETSCDATA(List));
printf( " - StylePositionImpl: %ld\n", (long)sizeof(GETSCDATA(Position)) );
totalSize += (long)sizeof(GETSCDATA(Position));
printf( " - StyleTextImpl: %ld\n", (long)sizeof(GETSCDATA(Text)) );
totalSize += (long)sizeof(GETSCDATA(Text));
printf( " - StyleDisplayImpl: %ld\n", (long)sizeof(GETSCDATA(Display)) );
totalSize += (long)sizeof(GETSCDATA(Display));
printf( " - StyleTableImpl: %ld\n", (long)sizeof(GETSCDATA(Table)) );
totalSize += (long)sizeof(GETSCDATA(Table));
printf( " - StyleContentImpl: %ld\n", (long)sizeof(GETSCDATA(Content)) );
totalSize += (long)sizeof(GETSCDATA(Content));
printf( " - StyleUserInterfaceImpl: %ld\n", (long)sizeof(GETSCDATA(UserInterface)) );
totalSize += (long)sizeof(GETSCDATA(UserInterface));
printf( " - StylePrintImpl: %ld\n", (long)sizeof(GETSCDATA(Print)));
totalSize += (long)sizeof(GETSCDATA(Print));
printf( " - Total: %ld\n", (long)totalSize);
printf( "*************************************\n");
}
// first get the unique items collection
UNIQUE_STYLE_ITEMS(uniqueItems);
if(! uniqueItems->AddItem((void*)this) ){
// object has already been accounted for
return;
}
PRUint32 localSize=0;
// get or create a tag for this instance
nsCOMPtr<nsIAtom> tag;
tag = getter_AddRefs(NS_NewAtom("StyleContextImpl"));
// get the size of an empty instance and add to the sizeof handler
aSize = sizeof(*this);
// add in the size of the member mPseudoTag
if(mPseudoTag){
mPseudoTag->SizeOf(aSizeOfHandler, &localSize);
aSize += localSize;
}
aSizeOfHandler->AddSize(tag,aSize);
#ifdef SHARE_STYLECONTEXTS
// count the style data seperately
if (mStyleData) {
mStyleData->SizeOf(aSizeOfHandler,localSize);
}
#endif
// size up the rules (if not already done)
// XXX - overhead of the collection???
if(mRules && uniqueItems->AddItem(mRules)){
PRUint32 curRule, ruleCount;
mRules->Count(&ruleCount);
if (ruleCount > 0) {
for (curRule = 0; curRule < ruleCount; curRule++) {
nsIStyleRule* rule = (nsIStyleRule*)mRules->ElementAt(curRule);
NS_ASSERTION(rule, "null entry in Rules list is bad news");
rule->SizeOf(aSizeOfHandler, localSize);
NS_RELEASE(rule);
}
}
}
// now follow up with the child (and empty child) recursion
if (nsnull != mChild) {
StyleContextImpl* child = mChild;
do {
child->SizeOf(aSizeOfHandler, localSize);
child = child->mNextSibling;
} while (mChild != child);
}
if (nsnull != mEmptyChild) {
StyleContextImpl* child = mEmptyChild;
do {
child->SizeOf(aSizeOfHandler, localSize);
child = child->mNextSibling;
} while (mEmptyChild != child);
}
// and finally our direct siblings (if any)
if (nsnull != mNextSibling) {
mNextSibling->SizeOf(aSizeOfHandler, localSize);
}
}
#ifdef DEBUG
static void IndentBy(FILE* out, PRInt32 aIndent) {
while (--aIndent >= 0) fputs(" ", out);
}
// virtual
void StyleContextImpl::DumpRegressionData(nsIPresContext* aPresContext, FILE* out, PRInt32 aIndent)
{
nsAutoString str;
// FONT
IndentBy(out,aIndent);
fprintf(out, "<font %s %s %d />\n",
NS_ConvertUCS2toUTF8(GETSCDATA(Font).mFont.name).get(),
NS_ConvertUCS2toUTF8(GETSCDATA(Font).mFixedFont.name).get(),
GETSCDATA(Font).mFlags);
// COLOR
IndentBy(out,aIndent);
fprintf(out, "<color data=\"%ld %d %d %d %ld %ld %ld %s %d %s %f\"/>\n",
(long)GETSCDATA(Color).mColor,
(int)GETSCDATA(Color).mBackgroundAttachment,
(int)GETSCDATA(Color).mBackgroundFlags,
(int)GETSCDATA(Color).mBackgroundRepeat,
(long)GETSCDATA(Color).mBackgroundColor,
(long)GETSCDATA(Color).mBackgroundXPosition,
(long)GETSCDATA(Color).mBackgroundYPosition,
NS_ConvertUCS2toUTF8(GETSCDATA(Color).mBackgroundImage).get(),
(int)GETSCDATA(Color).mCursor,
NS_ConvertUCS2toUTF8(GETSCDATA(Color).mCursorImage).get(),
GETSCDATA(Color).mOpacity);
// SPACING
IndentBy(out,aIndent);
fprintf(out, "<spacing data=\"");
GETSCDATA(Spacing).mMargin.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
GETSCDATA(Spacing).mPadding.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
GETSCDATA(Spacing).mBorder.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
GETSCDATA(Spacing).mBorderRadius.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
GETSCDATA(Spacing).mOutlineRadius.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
GETSCDATA(Spacing).mOutlineWidth.ToString(str);
fprintf(out, "%s", NS_ConvertUCS2toUTF8(str).get());
fprintf(out, "%d", (int)GETSCDATA(Spacing).mFloatEdge);
fprintf(out, "\" />\n");
// LIST
IndentBy(out,aIndent);
fprintf(out, "<list data=\"%d %d %s\" />\n",
(int)GETSCDATA(List).mListStyleType,
(int)GETSCDATA(List).mListStyleType,
NS_ConvertUCS2toUTF8(GETSCDATA(List).mListStyleImage).get());
// POSITION
IndentBy(out,aIndent);
fprintf(out, "<position data=\"%d ", (int)GETSCDATA(Position).mPosition);
GETSCDATA(Position).mOffset.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
GETSCDATA(Position).mWidth.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
GETSCDATA(Position).mMinWidth.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
GETSCDATA(Position).mMaxWidth.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
GETSCDATA(Position).mHeight.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
GETSCDATA(Position).mMinHeight.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
GETSCDATA(Position).mMaxHeight.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
fprintf(out, "%d ", (int)GETSCDATA(Position).mBoxSizing);
GETSCDATA(Position).mZIndex.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
fprintf(out, "\" />\n");
// TEXT
IndentBy(out,aIndent);
fprintf(out, "<text data=\"%d %d %d %d ",
(int)GETSCDATA(Text).mTextAlign,
(int)GETSCDATA(Text).mTextDecoration,
(int)GETSCDATA(Text).mTextTransform,
(int)GETSCDATA(Text).mWhiteSpace);
GETSCDATA(Text).mLetterSpacing.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
GETSCDATA(Text).mLineHeight.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
GETSCDATA(Text).mTextIndent.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
GETSCDATA(Text).mWordSpacing.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
GETSCDATA(Text).mVerticalAlign.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
fprintf(out, "\" />\n");
// DISPLAY
IndentBy(out,aIndent);
fprintf(out, "<display data=\"%d %d %d %d %d %d %d %d %d %ld %ld %ld %ld\" />\n",
(int)GETSCDATA(Display).mDirection,
(int)GETSCDATA(Display).mDisplay,
(int)GETSCDATA(Display).mFloats,
(int)GETSCDATA(Display).mBreakType,
(int)GETSCDATA(Display).mBreakBefore,
(int)GETSCDATA(Display).mBreakAfter,
(int)GETSCDATA(Display).mVisible,
(int)GETSCDATA(Display).mOverflow,
(int)GETSCDATA(Display).mClipFlags,
(long)GETSCDATA(Display).mClip.x,
(long)GETSCDATA(Display).mClip.y,
(long)GETSCDATA(Display).mClip.width,
(long)GETSCDATA(Display).mClip.height
);
// TABLE
IndentBy(out,aIndent);
fprintf(out, "<table data=\"%d %d %d %d ",
(int)GETSCDATA(Table).mLayoutStrategy,
(int)GETSCDATA(Table).mFrame,
(int)GETSCDATA(Table).mRules,
(int)GETSCDATA(Table).mBorderCollapse);
GETSCDATA(Table).mBorderSpacingX.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
GETSCDATA(Table).mBorderSpacingY.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
GETSCDATA(Table).mCellPadding.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
fprintf(out, "%d %d %ld %ld ",
(int)GETSCDATA(Table).mCaptionSide,
(int)GETSCDATA(Table).mEmptyCells,
(long)GETSCDATA(Table).mCols,
(long)GETSCDATA(Table).mSpan);
GETSCDATA(Table).mSpanWidth.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
fprintf(out, "\" />\n");
// CONTENT
IndentBy(out,aIndent);
fprintf(out, "<content data=\"%ld %ld %ld %ld ",
(long)GETSCDATA(Content).ContentCount(),
(long)GETSCDATA(Content).CounterIncrementCount(),
(long)GETSCDATA(Content).CounterResetCount(),
(long)GETSCDATA(Content).QuotesCount());
// XXX: iterate over the content, counters and quotes...
GETSCDATA(Content).mMarkerOffset.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
fprintf(out, "\" />\n");
// UI
IndentBy(out,aIndent);
fprintf(out, "<UI data=\"%d %d %d %d %d %d %s\" />\n",
(int)GETSCDATA(UserInterface).mUserInput,
(int)GETSCDATA(UserInterface).mUserModify,
(int)GETSCDATA(UserInterface).mUserSelect,
(int)GETSCDATA(UserInterface).mUserFocus,
(int)GETSCDATA(UserInterface).mKeyEquivalent,
(int)GETSCDATA(UserInterface).mResizer,
NS_ConvertUCS2toUTF8(GETSCDATA(UserInterface).mBehavior).get());
// PRINT
IndentBy(out,aIndent);
fprintf(out, "<print data=\"%d %d %d %s %ld %ld %d ",
(int)GETSCDATA(Print).mPageBreakBefore,
(int)GETSCDATA(Print).mPageBreakAfter,
(int)GETSCDATA(Print).mPageBreakInside,
NS_ConvertUCS2toUTF8(GETSCDATA(Print).mPage).get(),
(long)GETSCDATA(Print).mWidows,
(long)GETSCDATA(Print).mOrphans,
(int)GETSCDATA(Print).mMarks);
GETSCDATA(Print).mSizeWidth.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
fprintf(out, "\" />\n");
}
#endif
1998-04-14 00:24:54 +04:00
NS_LAYOUT nsresult
NS_NewStyleContext(nsIStyleContext** aInstancePtrResult,
nsIStyleContext* aParentContext,
nsIAtom* aPseudoTag,
1998-04-14 00:24:54 +04:00
nsISupportsArray* aRules,
nsIPresContext* aPresContext)
1998-04-14 00:24:54 +04:00
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
StyleContextImpl* context = new StyleContextImpl(aParentContext, aPseudoTag,
aRules, aPresContext);
1998-04-14 00:24:54 +04:00
if (nsnull == context) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsresult result = context->QueryInterface(kIStyleContextIID, (void **) aInstancePtrResult);
context->RemapStyle(aPresContext); // remap after initial ref-count is set
#ifdef SHARE_STYLECONTEXTS
context->UpdateStyleSetCache(); // add it to the style set cache
#endif
return result;
1998-04-14 00:24:54 +04:00
}
//----------------------------------------------------------
#ifdef COMPUTE_STYLEDATA_CRC
/*************************************************************************
* The table lookup technique was adapted from the algorithm described *
* by Avram Perez, Byte-wise CRC Calculations, IEEE Micro 3, 40 (1983). *
*************************************************************************/
#define POLYNOMIAL 0x04c11db7L
static PRBool crc_table_initialized;
static PRUint32 crc_table[256];
void gen_crc_table() {
/* generate the table of CRC remainders for all possible bytes */
int i, j;
PRUint32 crc_accum;
for ( i = 0; i < 256; i++ ) {
crc_accum = ( (unsigned long) i << 24 );
for ( j = 0; j < 8; j++ ) {
if ( crc_accum & 0x80000000L )
crc_accum = ( crc_accum << 1 ) ^ POLYNOMIAL;
else crc_accum = ( crc_accum << 1 );
}
crc_table[i] = crc_accum;
}
return;
}
PRUint32 AccumulateCRC(PRUint32 crc_accum, const char *data_blk_ptr, int data_blk_size) {
if (!crc_table_initialized) {
gen_crc_table();
crc_table_initialized = PR_TRUE;
}
/* update the CRC on the data block one byte at a time */
int i, j;
for ( j = 0; j < data_blk_size; j++ ) {
i = ( (int) ( crc_accum >> 24) ^ *data_blk_ptr++ ) & 0xff;
crc_accum = ( crc_accum << 8 ) ^ crc_table[i];
}
return crc_accum;
}
PRUint32 StyleSideCRC(PRUint32 aCrc,const nsStyleSides *aStyleSides)
{
PRUint32 crc = 0;
nsStyleCoord theCoord;
aStyleSides->GetLeft(theCoord);
crc = StyleCoordCRC(crc,&theCoord);
aStyleSides->GetTop(theCoord);
crc = StyleCoordCRC(crc,&theCoord);
aStyleSides->GetRight(theCoord);
crc = StyleCoordCRC(crc,&theCoord);
aStyleSides->GetBottom(theCoord);
crc = StyleCoordCRC(crc,&theCoord);
return crc;
}
PRUint32 StyleCoordCRC(PRUint32 aCrc, const nsStyleCoord* aCoord)
{
PRUint32 crc = aCrc;
crc = AccumulateCRC(crc,(const char *)&aCoord->mUnit,sizeof(aCoord->mUnit));
// using the mInt part of the union below (float and PRInt32 should be the same size...)
crc = AccumulateCRC(crc,(const char *)&aCoord->mValue.mInt,sizeof(aCoord->mValue.mInt));
return crc;
}
PRUint32 StyleMarginCRC(PRUint32 aCrc, const nsMargin *aMargin)
{
PRUint32 crc = aCrc;
crc = AccumulateCRC(crc,(const char *)&aMargin->left,sizeof(aMargin->left));
crc = AccumulateCRC(crc,(const char *)&aMargin->top,sizeof(aMargin->top));
crc = AccumulateCRC(crc,(const char *)&aMargin->right,sizeof(aMargin->right));
crc = AccumulateCRC(crc,(const char *)&aMargin->bottom,sizeof(aMargin->bottom));
return crc;
}
PRUint32 StyleStringCRC(PRUint32 aCrc, const nsString *aString)
{
PRUint32 crc = aCrc;
PRUint32 len = aString->Length();
const PRUnichar *p = aString->GetUnicode();
if (p) {
crc = AccumulateCRC(crc,(const char *)p,(len*2));
}
crc = AccumulateCRC(crc,(const char *)&len,sizeof(len));
return crc;
}
#endif // #ifdef COMPUTE_STYLEDATA_CRC
void EnsureBlockDisplay(/*in out*/PRUint8 &display)
{
// see if the display value is already a block
switch (display) {
case NS_STYLE_DISPLAY_NONE :
// never change display:none *ever*
break;
case NS_STYLE_DISPLAY_TABLE :
case NS_STYLE_DISPLAY_BLOCK :
// do not muck with these at all - already blocks
break;
case NS_STYLE_DISPLAY_TABLE_ROW_GROUP :
case NS_STYLE_DISPLAY_TABLE_COLUMN :
case NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP :
case NS_STYLE_DISPLAY_TABLE_HEADER_GROUP :
case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP :
case NS_STYLE_DISPLAY_TABLE_ROW :
case NS_STYLE_DISPLAY_TABLE_CELL :
case NS_STYLE_DISPLAY_TABLE_CAPTION :
// special cases: don't do anything since these cannot really be floated anyway
break;
case NS_STYLE_DISPLAY_INLINE_TABLE :
// make inline tables into tables
display = NS_STYLE_DISPLAY_TABLE;
break;
default :
// make it a block
display = NS_STYLE_DISPLAY_BLOCK;
}
}