mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-01 06:35:42 +00:00
4514 lines
142 KiB
C++
4514 lines
142 KiB
C++
/* -*- 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/
|
|
*
|
|
* 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.
|
|
*
|
|
* The Original Code is mozilla.org code.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape
|
|
* 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
|
|
*
|
|
*/
|
|
|
|
#include "nsIStyleContext.h"
|
|
#include "nsIMutableStyleContext.h"
|
|
#include "nsStyleConsts.h"
|
|
#include "nsString.h"
|
|
#include "nsUnitConversion.h"
|
|
#include "nsIPresContext.h"
|
|
#include "nsIStyleRule.h"
|
|
#include "nsISupportsArray.h"
|
|
#include "nsCRT.h"
|
|
|
|
#include "nsCOMPtr.h"
|
|
#include "nsIStyleSet.h"
|
|
#include "nsISizeOfHandler.h"
|
|
#include "nsIPresShell.h"
|
|
#include "nsLayoutAtoms.h"
|
|
#include "prenv.h"
|
|
|
|
#ifdef IBMBIDI
|
|
#include "nsIUBidiUtils.h"
|
|
#endif
|
|
|
|
#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);
|
|
#define STYLEDATA_NO_CRC (0)
|
|
#define STYLEDATA_DEFAULT_CRC (0xcafebabe)
|
|
#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);
|
|
|
|
// --------------------
|
|
// nsStyleFont
|
|
//
|
|
nsStyleFont::nsStyleFont(const nsFont& aVariableFont, const nsFont& aFixedFont)
|
|
: mFont(aVariableFont),
|
|
mFixedFont(aFixedFont)
|
|
{ }
|
|
|
|
struct StyleFontImpl : public nsStyleFont {
|
|
StyleFontImpl(const nsFont& aVariableFont, const nsFont& aFixedFont)
|
|
: nsStyleFont(aVariableFont, aFixedFont)
|
|
{}
|
|
|
|
void ResetFrom(const nsStyleFont* aParent, nsIPresContext* aPresContext);
|
|
void SetFrom(const nsStyleFont& aSource);
|
|
void CopyTo(nsStyleFont& aDest) const;
|
|
PRInt32 CalcDifference(const StyleFontImpl& aOther) const;
|
|
static PRInt32 CalcFontDifference(const nsFont& aFont1, const nsFont& aFont2);
|
|
PRUint32 ComputeCRC32(PRUint32 crc) const;
|
|
|
|
private: // These are not allowed
|
|
StyleFontImpl(const StyleFontImpl& aOther);
|
|
StyleFontImpl& operator=(const StyleFontImpl& aOther);
|
|
};
|
|
|
|
void StyleFontImpl::ResetFrom(const nsStyleFont* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
if (nsnull != aParent) {
|
|
mFont = aParent->mFont;
|
|
mFixedFont = aParent->mFixedFont;
|
|
mFlags = aParent->mFlags;
|
|
}
|
|
else {
|
|
aPresContext->GetDefaultFont(mFont);
|
|
aPresContext->GetDefaultFixedFont(mFixedFont);
|
|
mFlags = NS_STYLE_FONT_DEFAULT;
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
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;
|
|
}
|
|
|
|
#ifdef XP_MAC
|
|
#pragma mark -
|
|
#endif
|
|
|
|
// --------------------
|
|
// nsStyleColor
|
|
//
|
|
|
|
struct StyleColorImpl: public nsStyleColor {
|
|
StyleColorImpl(void) { }
|
|
|
|
void ResetFrom(const nsStyleColor* aParent, nsIPresContext* aPresContext);
|
|
void SetFrom(const nsStyleColor& aSource);
|
|
void CopyTo(nsStyleColor& aDest) const;
|
|
PRInt32 CalcDifference(const StyleColorImpl& aOther) const;
|
|
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
|
|
|
|
private: // These are not allowed
|
|
StyleColorImpl(const StyleColorImpl& aOther);
|
|
StyleColorImpl& operator=(const StyleColorImpl& aOther);
|
|
};
|
|
|
|
void StyleColorImpl::ResetFrom(const nsStyleColor* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
if (nsnull != aParent) {
|
|
mColor = aParent->mColor;
|
|
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);
|
|
}
|
|
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;
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
#ifdef XP_MAC
|
|
#pragma mark -
|
|
#endif
|
|
|
|
static PRBool IsFixedData(const nsStyleSides& aSides, PRBool aEnumOK)
|
|
{
|
|
return PRBool(IsFixedUnit(aSides.GetLeftUnit(), aEnumOK) &&
|
|
IsFixedUnit(aSides.GetTopUnit(), aEnumOK) &&
|
|
IsFixedUnit(aSides.GetRightUnit(), aEnumOK) &&
|
|
IsFixedUnit(aSides.GetBottomUnit(), aEnumOK));
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
#ifdef XP_MAC
|
|
#pragma mark -
|
|
#endif
|
|
|
|
struct StyleMarginImpl: public nsStyleMargin {
|
|
StyleMarginImpl(void)
|
|
: nsStyleMargin()
|
|
{}
|
|
|
|
void ResetFrom(const nsStyleMargin* aParent, nsIPresContext* aPresContext);
|
|
void SetFrom(const nsStyleMargin& aSource);
|
|
void CopyTo(nsStyleMargin& aDest) const;
|
|
void RecalcData(void);
|
|
PRInt32 CalcDifference(const StyleMarginImpl& aOther) const;
|
|
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
|
|
|
|
private: // These are not allowed
|
|
StyleMarginImpl(const StyleMarginImpl& aOther);
|
|
StyleMarginImpl& operator=(const StyleMarginImpl& aOther);
|
|
};
|
|
|
|
void StyleMarginImpl::ResetFrom(const nsStyleMargin* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
// spacing values not inherited
|
|
mMargin.Reset();
|
|
mHasCachedMargin = PR_FALSE;
|
|
}
|
|
|
|
void StyleMarginImpl::SetFrom(const nsStyleMargin& aSource)
|
|
{
|
|
nsCRT::memcpy((nsStyleMargin*)this, &aSource, sizeof(nsStyleMargin));
|
|
}
|
|
|
|
void StyleMarginImpl::CopyTo(nsStyleMargin& aDest) const
|
|
{
|
|
nsCRT::memcpy(&aDest, (const nsStyleMargin*)this, sizeof(nsStyleMargin));
|
|
}
|
|
|
|
void StyleMarginImpl::RecalcData(void)
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
|
|
PRInt32 StyleMarginImpl::CalcDifference(const StyleMarginImpl& aOther) const
|
|
{
|
|
if (mMargin == aOther.mMargin) {
|
|
return NS_STYLE_HINT_NONE;
|
|
}
|
|
return NS_STYLE_HINT_REFLOW;
|
|
}
|
|
|
|
PRUint32 StyleMarginImpl::ComputeCRC32(PRUint32 aCrc) const
|
|
{
|
|
PRUint32 crc = aCrc;
|
|
|
|
#ifdef COMPUTE_STYLEDATA_CRC
|
|
crc = StyleSideCRC(crc,&mMargin);
|
|
crc = AccumulateCRC(crc,(const char *)&mHasCachedMargin,sizeof(mHasCachedMargin));
|
|
if (mHasCachedMargin) {
|
|
crc = StyleMarginCRC(crc,&mCachedMargin);
|
|
}
|
|
#endif
|
|
return crc;
|
|
}
|
|
|
|
|
|
#ifdef XP_MAC
|
|
#pragma mark -
|
|
#endif
|
|
|
|
struct StylePaddingImpl: public nsStylePadding {
|
|
StylePaddingImpl(void)
|
|
: nsStylePadding()
|
|
{}
|
|
|
|
void ResetFrom(const nsStylePadding* aParent, nsIPresContext* aPresContext);
|
|
void SetFrom(const nsStylePadding& aSource);
|
|
void CopyTo(nsStylePadding& aDest) const;
|
|
void RecalcData(void);
|
|
PRInt32 CalcDifference(const StylePaddingImpl& aOther) const;
|
|
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
|
|
|
|
private: // These are not allowed
|
|
StylePaddingImpl(const StylePaddingImpl& aOther);
|
|
StylePaddingImpl& operator=(const StylePaddingImpl& aOther);
|
|
};
|
|
|
|
void StylePaddingImpl::ResetFrom(const nsStylePadding* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
// spacing values not inherited
|
|
mPadding.Reset();
|
|
mHasCachedPadding = PR_FALSE;
|
|
}
|
|
|
|
void StylePaddingImpl::SetFrom(const nsStylePadding& aSource)
|
|
{
|
|
nsCRT::memcpy((nsStylePadding*)this, &aSource, sizeof(nsStylePadding));
|
|
}
|
|
|
|
void StylePaddingImpl::CopyTo(nsStylePadding& aDest) const
|
|
{
|
|
nsCRT::memcpy(&aDest, (const nsStylePadding*)this, sizeof(nsStylePadding));
|
|
}
|
|
|
|
void StylePaddingImpl::RecalcData(void)
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
|
|
PRInt32 StylePaddingImpl::CalcDifference(const StylePaddingImpl& aOther) const
|
|
{
|
|
if (mPadding == aOther.mPadding) {
|
|
return NS_STYLE_HINT_NONE;
|
|
}
|
|
return NS_STYLE_HINT_REFLOW;
|
|
}
|
|
|
|
PRUint32 StylePaddingImpl::ComputeCRC32(PRUint32 aCrc) const
|
|
{
|
|
PRUint32 crc = aCrc;
|
|
|
|
#ifdef COMPUTE_STYLEDATA_CRC
|
|
crc = StyleSideCRC(crc,&mPadding);
|
|
crc = AccumulateCRC(crc,(const char *)&mHasCachedPadding,sizeof(mHasCachedPadding));
|
|
if (mHasCachedPadding) {
|
|
crc = StyleMarginCRC(crc,&mCachedPadding);
|
|
}
|
|
#endif
|
|
return crc;
|
|
}
|
|
|
|
|
|
#ifdef XP_MAC
|
|
#pragma mark -
|
|
#endif
|
|
|
|
struct StyleBorderImpl: public nsStyleBorder {
|
|
StyleBorderImpl(void)
|
|
: nsStyleBorder(), mWidthsInitialized(PR_FALSE)
|
|
{}
|
|
|
|
void ResetFrom(const nsStyleBorder* aParent, nsIPresContext* aPresContext);
|
|
void SetFrom(const nsStyleBorder& aSource);
|
|
void CopyTo(nsStyleBorder& aDest) const;
|
|
PRBool IsBorderSideVisible(PRUint8 aSide) const;
|
|
void RecalcData(nscolor color);
|
|
PRInt32 CalcDifference(const StyleBorderImpl& aOther) const;
|
|
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
|
|
|
|
private: // These are not allowed
|
|
StyleBorderImpl(const StyleBorderImpl& aOther);
|
|
StyleBorderImpl& operator=(const StyleBorderImpl& aOther);
|
|
|
|
// XXX remove with deprecated methods
|
|
PRBool mWidthsInitialized;
|
|
};
|
|
|
|
void StyleBorderImpl::ResetFrom(const nsStyleBorder* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
// XXX support mBorderWidhts until deprecated methods are removed
|
|
if (! mWidthsInitialized) {
|
|
float pixelsToTwips = 20.0f;
|
|
if (aPresContext) {
|
|
aPresContext->GetPixelsToTwips(&pixelsToTwips);
|
|
}
|
|
mBorderWidths[NS_STYLE_BORDER_WIDTH_THIN] = NSIntPixelsToTwips(1, pixelsToTwips);
|
|
mBorderWidths[NS_STYLE_BORDER_WIDTH_MEDIUM] = NSIntPixelsToTwips(3, pixelsToTwips);
|
|
mBorderWidths[NS_STYLE_BORDER_WIDTH_THICK] = NSIntPixelsToTwips(5, pixelsToTwips);
|
|
mWidthsInitialized = PR_TRUE;
|
|
}
|
|
|
|
// spacing values not inherited
|
|
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();
|
|
|
|
mFloatEdge = NS_STYLE_FLOAT_EDGE_CONTENT;
|
|
|
|
mHasCachedBorder = PR_FALSE;
|
|
}
|
|
|
|
void StyleBorderImpl::SetFrom(const nsStyleBorder& aSource)
|
|
{
|
|
nsCRT::memcpy((nsStyleBorder*)this, &aSource, sizeof(nsStyleBorder));
|
|
}
|
|
|
|
void StyleBorderImpl::CopyTo(nsStyleBorder& aDest) const
|
|
{
|
|
nsCRT::memcpy(&aDest, (const nsStyleBorder*)this, sizeof(nsStyleBorder));
|
|
}
|
|
|
|
PRBool StyleBorderImpl::IsBorderSideVisible(PRUint8 aSide) const
|
|
{
|
|
PRUint8 borderStyle = GetBorderStyle(aSide);
|
|
return ((borderStyle != NS_STYLE_BORDER_STYLE_NONE)
|
|
&& (borderStyle != NS_STYLE_BORDER_STYLE_HIDDEN));
|
|
}
|
|
|
|
void StyleBorderImpl::RecalcData(nscolor aColor)
|
|
{
|
|
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), mBorderWidths, 3);
|
|
}
|
|
if (!IsBorderSideVisible(NS_SIDE_TOP)) {
|
|
mCachedBorder.top = 0;
|
|
}
|
|
else {
|
|
mCachedBorder.top = CalcCoord(mBorder.GetTop(coord), mBorderWidths, 3);
|
|
}
|
|
if (!IsBorderSideVisible(NS_SIDE_RIGHT)) {
|
|
mCachedBorder.right = 0;
|
|
}
|
|
else {
|
|
mCachedBorder.right = CalcCoord(mBorder.GetRight(coord), mBorderWidths, 3);
|
|
}
|
|
if (!IsBorderSideVisible(NS_SIDE_BOTTOM)) {
|
|
mCachedBorder.bottom = 0;
|
|
}
|
|
else {
|
|
mCachedBorder.bottom = CalcCoord(mBorder.GetBottom(coord), mBorderWidths, 3);
|
|
}
|
|
mHasCachedBorder = PR_TRUE;
|
|
}
|
|
else {
|
|
mHasCachedBorder = PR_FALSE;
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
PRInt32 StyleBorderImpl::CalcDifference(const StyleBorderImpl& aOther) const
|
|
{
|
|
if ((mBorder == aOther.mBorder) &&
|
|
(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]))) {
|
|
return NS_STYLE_HINT_REFLOW; // border on or off
|
|
}
|
|
return NS_STYLE_HINT_VISUAL;
|
|
}
|
|
}
|
|
if (mBorderRadius != aOther.mBorderRadius) {
|
|
return NS_STYLE_HINT_VISUAL;
|
|
}
|
|
return NS_STYLE_HINT_NONE;
|
|
}
|
|
return NS_STYLE_HINT_REFLOW;
|
|
}
|
|
|
|
PRUint32 StyleBorderImpl::ComputeCRC32(PRUint32 aCrc) const
|
|
{
|
|
PRUint32 crc = aCrc;
|
|
|
|
#ifdef COMPUTE_STYLEDATA_CRC
|
|
crc = StyleSideCRC(crc,&mBorder);
|
|
crc = StyleSideCRC(crc,&mBorderRadius);
|
|
crc = AccumulateCRC(crc,(const char *)&mFloatEdge,sizeof(mFloatEdge));
|
|
crc = AccumulateCRC(crc,(const char *)&mHasCachedBorder,sizeof(mHasCachedBorder));
|
|
if (mHasCachedBorder) {
|
|
crc = StyleMarginCRC(crc,&mCachedBorder);
|
|
}
|
|
crc = AccumulateCRC(crc,(const char *)mBorderStyle,sizeof(mBorderStyle)); // array of 4 elements
|
|
crc = AccumulateCRC(crc,(const char *)mBorderColor,sizeof(mBorderColor)); // array ...
|
|
#endif
|
|
return crc;
|
|
}
|
|
|
|
|
|
#ifdef XP_MAC
|
|
#pragma mark -
|
|
#endif
|
|
|
|
struct StyleOutlineImpl: public nsStyleOutline {
|
|
StyleOutlineImpl(void)
|
|
: nsStyleOutline(), mWidthsInitialized(PR_FALSE)
|
|
{}
|
|
|
|
void ResetFrom(const nsStyleOutline* aParent, nsIPresContext* aPresContext);
|
|
void SetFrom(const nsStyleOutline& aSource);
|
|
void CopyTo(nsStyleOutline& aDest) const;
|
|
void RecalcData(void);
|
|
PRInt32 CalcDifference(const StyleOutlineImpl& aOther) const;
|
|
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
|
|
|
|
private: // These are not allowed
|
|
StyleOutlineImpl(const StyleOutlineImpl& aOther);
|
|
StyleOutlineImpl& operator=(const StyleOutlineImpl& aOther);
|
|
|
|
// XXX remove with deprecated methods
|
|
PRBool mWidthsInitialized;
|
|
};
|
|
|
|
void StyleOutlineImpl::ResetFrom(const nsStyleOutline* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
// XXX support mBorderWidhts until deprecated methods are removed
|
|
if (! mWidthsInitialized) {
|
|
float pixelsToTwips = 20.0f;
|
|
if (aPresContext) {
|
|
aPresContext->GetPixelsToTwips(&pixelsToTwips);
|
|
}
|
|
mBorderWidths[NS_STYLE_BORDER_WIDTH_THIN] = NSIntPixelsToTwips(1, pixelsToTwips);
|
|
mBorderWidths[NS_STYLE_BORDER_WIDTH_MEDIUM] = NSIntPixelsToTwips(3, pixelsToTwips);
|
|
mBorderWidths[NS_STYLE_BORDER_WIDTH_THICK] = NSIntPixelsToTwips(5, pixelsToTwips);
|
|
mWidthsInitialized = PR_TRUE;
|
|
}
|
|
|
|
// spacing values not inherited
|
|
mOutlineRadius.Reset();
|
|
|
|
nsStyleCoord medium(NS_STYLE_BORDER_WIDTH_MEDIUM, eStyleUnit_Enumerated);
|
|
mOutlineWidth = medium;
|
|
mOutlineStyle = NS_STYLE_BORDER_STYLE_NONE;
|
|
mOutlineColor = NS_RGB(0, 0, 0);
|
|
|
|
mHasCachedOutline = PR_FALSE;
|
|
}
|
|
|
|
void StyleOutlineImpl::SetFrom(const nsStyleOutline& aSource)
|
|
{
|
|
nsCRT::memcpy((nsStyleOutline*)this, &aSource, sizeof(nsStyleOutline));
|
|
}
|
|
|
|
void StyleOutlineImpl::CopyTo(nsStyleOutline& aDest) const
|
|
{
|
|
nsCRT::memcpy(&aDest, (const nsStyleOutline*)this, sizeof(nsStyleOutline));
|
|
}
|
|
|
|
void StyleOutlineImpl::RecalcData(void)
|
|
{
|
|
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, mBorderWidths, 3);
|
|
}
|
|
mHasCachedOutline = PR_TRUE;
|
|
}
|
|
else {
|
|
mHasCachedOutline = PR_FALSE;
|
|
}
|
|
}
|
|
|
|
PRInt32 StyleOutlineImpl::CalcDifference(const StyleOutlineImpl& aOther) const
|
|
{
|
|
if ((mOutlineWidth != aOther.mOutlineWidth) ||
|
|
(mOutlineStyle != aOther.mOutlineStyle) ||
|
|
(mOutlineColor != aOther.mOutlineColor) ||
|
|
(mOutlineRadius != aOther.mOutlineRadius)) {
|
|
return NS_STYLE_HINT_VISUAL; // XXX: should be VISUAL: see bugs 9809 and 9816
|
|
}
|
|
return NS_STYLE_HINT_NONE;
|
|
}
|
|
|
|
PRUint32 StyleOutlineImpl::ComputeCRC32(PRUint32 aCrc) const
|
|
{
|
|
PRUint32 crc = aCrc;
|
|
|
|
#ifdef COMPUTE_STYLEDATA_CRC
|
|
crc = StyleSideCRC(crc,&mOutlineRadius);
|
|
crc = StyleCoordCRC(crc,&mOutlineWidth);
|
|
crc = AccumulateCRC(crc,(const char *)&mHasCachedOutline,sizeof(mHasCachedOutline));
|
|
if (mHasCachedOutline) {
|
|
crc = AccumulateCRC(crc,(const char *)&mCachedOutlineWidth,sizeof(mCachedOutlineWidth));
|
|
}
|
|
crc = AccumulateCRC(crc,(const char *)&mOutlineStyle,sizeof(mOutlineStyle));
|
|
crc = AccumulateCRC(crc,(const char *)&mOutlineColor,sizeof(mOutlineColor));
|
|
#endif
|
|
return crc;
|
|
}
|
|
|
|
#ifdef XP_MAC
|
|
#pragma mark -
|
|
#endif
|
|
// --------------------
|
|
// nsStyleList
|
|
//
|
|
nsStyleList::nsStyleList(void) { }
|
|
nsStyleList::~nsStyleList(void) { }
|
|
|
|
struct StyleListImpl: public nsStyleList {
|
|
StyleListImpl(void) { }
|
|
|
|
void ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresContext);
|
|
void SetFrom(const nsStyleList& aSource);
|
|
void CopyTo(nsStyleList& aDest) const;
|
|
PRInt32 CalcDifference(const StyleListImpl& aOther) const;
|
|
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
|
|
|
|
private: // These are not allowed
|
|
StyleListImpl(const StyleListImpl& aOther);
|
|
StyleListImpl& operator=(const StyleListImpl& aOther);
|
|
};
|
|
|
|
void StyleListImpl::ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
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();
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
return NS_STYLE_HINT_REFLOW;
|
|
}
|
|
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;
|
|
}
|
|
|
|
#ifdef XP_MAC
|
|
#pragma mark -
|
|
#endif
|
|
|
|
// --------------------
|
|
// nsStylePosition
|
|
//
|
|
nsStylePosition::nsStylePosition(void) { }
|
|
nsStylePosition::~nsStylePosition(void) { }
|
|
|
|
struct StylePositionImpl: public nsStylePosition {
|
|
StylePositionImpl(void) { }
|
|
|
|
void ResetFrom(const nsStylePosition* aParent, nsIPresContext* aPresContext);
|
|
void SetFrom(const nsStylePosition& aSource);
|
|
void CopyTo(nsStylePosition& aDest) const;
|
|
PRInt32 CalcDifference(const StylePositionImpl& aOther) const;
|
|
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
|
|
|
|
private: // These are not allowed
|
|
StylePositionImpl(const StylePositionImpl& aOther);
|
|
StylePositionImpl& operator=(const StylePositionImpl& aOther);
|
|
};
|
|
|
|
void StylePositionImpl::ResetFrom(const nsStylePosition* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
// 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();
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
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) &&
|
|
(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;
|
|
}
|
|
|
|
#ifdef XP_MAC
|
|
#pragma mark -
|
|
#endif
|
|
|
|
// --------------------
|
|
// nsStyleText
|
|
//
|
|
|
|
nsStyleText::nsStyleText(void) { }
|
|
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;
|
|
PRInt32 CalcDifference(const StyleTextImpl& aOther) const;
|
|
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
|
|
|
|
private: // These are not allowed
|
|
StyleTextImpl(const StyleTextImpl& aOther);
|
|
StyleTextImpl& operator=(const StyleTextImpl& aOther);
|
|
};
|
|
|
|
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;
|
|
#ifdef IBMBIDI
|
|
mUnicodeBidi = aParent->mUnicodeBidi;
|
|
#endif // IBMBIDI
|
|
}
|
|
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();
|
|
#ifdef IBMBIDI
|
|
mUnicodeBidi = NS_STYLE_UNICODE_BIDI_INHERIT;
|
|
#endif // IBMBIDI
|
|
}
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
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) &&
|
|
#ifdef IBMBIDI
|
|
(mUnicodeBidi == aOther.mUnicodeBidi) &&
|
|
#endif // IBMBIDI
|
|
(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);
|
|
#ifdef IBMBIDI
|
|
crc = AccumulateCRC(crc,(const char *)&mUnicodeBidi,sizeof(mUnicodeBidi));
|
|
#endif // IBMBIDI
|
|
#endif
|
|
return crc;
|
|
}
|
|
|
|
#ifdef XP_MAC
|
|
#pragma mark -
|
|
#endif
|
|
|
|
// --------------------
|
|
// nsStyleDisplay
|
|
//
|
|
|
|
struct StyleDisplayImpl: public nsStyleDisplay {
|
|
StyleDisplayImpl(void) { }
|
|
|
|
void ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* aPresContext);
|
|
void SetFrom(const nsStyleDisplay& aSource);
|
|
void CopyTo(nsStyleDisplay& aDest) const;
|
|
PRInt32 CalcDifference(const StyleDisplayImpl& aOther) const;
|
|
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
|
|
|
|
private: // These are not allowed
|
|
StyleDisplayImpl(const StyleDisplayImpl& aOther);
|
|
StyleDisplayImpl& operator=(const StyleDisplayImpl& aOther);
|
|
};
|
|
|
|
void StyleDisplayImpl::ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
if (nsnull != aParent) {
|
|
mDirection = aParent->mDirection;
|
|
mLanguage = aParent->mLanguage;
|
|
mVisible = aParent->mVisible;
|
|
}
|
|
else {
|
|
#ifdef IBMBIDI
|
|
PRUint32 mBidioptions;
|
|
aPresContext->GetBidi(&mBidioptions);
|
|
if (GET_BIDI_OPTION_DIRECTION(mBidioptions) == IBMBIDI_TEXTDIRECTION_RTL)
|
|
mDirection = NS_STYLE_DIRECTION_RTL;
|
|
else
|
|
mDirection = NS_STYLE_DIRECTION_LTR;
|
|
#else // ifdef IBMBIDI
|
|
aPresContext->GetDefaultDirection(&mDirection);
|
|
#endif // IBMBIDI
|
|
aPresContext->GetLanguage(getter_AddRefs(mLanguage));
|
|
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);
|
|
#ifdef IBMBIDI
|
|
mExplicitDirection = NS_STYLE_DIRECTION_INHERIT;
|
|
#endif // IBMBIDI
|
|
}
|
|
|
|
void StyleDisplayImpl::SetFrom(const nsStyleDisplay& aSource)
|
|
{
|
|
mDirection = aSource.mDirection;
|
|
#ifdef IBMBIDI
|
|
mExplicitDirection = aSource.mExplicitDirection;
|
|
#endif // IBMBIDI
|
|
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;
|
|
#ifdef IBMBIDI
|
|
aDest.mExplicitDirection = mExplicitDirection;
|
|
#endif // IBMBIDI
|
|
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;
|
|
}
|
|
|
|
PRInt32 StyleDisplayImpl::CalcDifference(const StyleDisplayImpl& aOther) const
|
|
{
|
|
if ((mDisplay == aOther.mDisplay) &&
|
|
(mFloats == aOther.mFloats) &&
|
|
(mOverflow == aOther.mOverflow)) {
|
|
if ((mDirection == aOther.mDirection) &&
|
|
(mLanguage == aOther.mLanguage) &&
|
|
(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;
|
|
}
|
|
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));
|
|
#ifdef IBMBIDI
|
|
crc = AccumulateCRC(crc,(const char *)&mExplicitDirection,sizeof(mExplicitDirection));
|
|
#endif // IBMBIDI
|
|
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;
|
|
}
|
|
|
|
#ifdef XP_MAC
|
|
#pragma mark -
|
|
#endif
|
|
|
|
// --------------------
|
|
// nsStyleTable
|
|
//
|
|
|
|
nsStyleTable::nsStyleTable(void) { }
|
|
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;
|
|
PRInt32 CalcDifference(const StyleTableImpl& aOther) const;
|
|
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
|
|
|
|
private: // These are not allowed
|
|
StyleTableImpl(const StyleTableImpl& aOther);
|
|
StyleTableImpl& operator=(const StyleTableImpl& aOther);
|
|
};
|
|
|
|
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();
|
|
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);
|
|
|
|
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));
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
#ifdef XP_MAC
|
|
#pragma mark -
|
|
#endif
|
|
|
|
//-----------------------
|
|
// 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);
|
|
}
|
|
|
|
|
|
struct StyleContentImpl: public nsStyleContent {
|
|
StyleContentImpl(void) : nsStyleContent() { };
|
|
|
|
void ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPresContext);
|
|
void SetFrom(const nsStyleContent& aSource);
|
|
void CopyTo(nsStyleContent& aDest) const;
|
|
PRInt32 CalcDifference(const StyleContentImpl& aOther) const;
|
|
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
|
|
|
|
private: // These are not allowed
|
|
StyleContentImpl(const StyleContentImpl& aOther);
|
|
StyleContentImpl& operator=(const StyleContentImpl& aOther);
|
|
};
|
|
|
|
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];
|
|
}
|
|
}
|
|
}
|
|
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]);
|
|
}
|
|
}
|
|
}
|
|
|
|
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)) {
|
|
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)) {
|
|
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)) {
|
|
return NS_STYLE_HINT_REFLOW;
|
|
}
|
|
}
|
|
ix = (mQuotesCount * 2);
|
|
while (0 < ix--) {
|
|
if (mQuotes[ix] != aOther.mQuotes[ix]) {
|
|
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;
|
|
}
|
|
|
|
#ifdef XP_MAC
|
|
#pragma mark -
|
|
#endif
|
|
|
|
//-----------------------
|
|
// nsStyleUserInterface
|
|
//
|
|
|
|
nsStyleUserInterface::nsStyleUserInterface(void) { }
|
|
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;
|
|
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;
|
|
}
|
|
|
|
#ifdef XP_MAC
|
|
#pragma mark -
|
|
#endif
|
|
|
|
//-----------------------
|
|
// nsStylePrint
|
|
//
|
|
|
|
nsStylePrint::nsStylePrint(void) { }
|
|
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 XP_MAC
|
|
#pragma mark -
|
|
#endif
|
|
|
|
#ifdef INCLUDE_XUL
|
|
// --------------------
|
|
// nsStyleXUL
|
|
//
|
|
nsStyleXUL::nsStyleXUL() { }
|
|
nsStyleXUL::~nsStyleXUL() { }
|
|
|
|
struct StyleXULImpl: public nsStyleXUL {
|
|
StyleXULImpl() { }
|
|
|
|
void ResetFrom(const nsStyleXUL* aParent, nsIPresContext* aPresContext);
|
|
void SetFrom(const nsStyleXUL& aSource);
|
|
void CopyTo(nsStyleXUL& aDest) const;
|
|
PRInt32 CalcDifference(const StyleXULImpl& aOther) const;
|
|
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
|
|
|
|
private: // These are not allowed
|
|
StyleXULImpl(const StyleXULImpl& aOther);
|
|
StyleXULImpl& operator=(const StyleXULImpl& aOther);
|
|
};
|
|
|
|
void StyleXULImpl::ResetFrom(const nsStyleXUL* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
mBoxOrient = NS_STYLE_BOX_ORIENT_HORIZONTAL;
|
|
}
|
|
|
|
void StyleXULImpl::SetFrom(const nsStyleXUL& aSource)
|
|
{
|
|
nsCRT::memcpy((nsStyleXUL*)this, &aSource, sizeof(nsStyleXUL));
|
|
}
|
|
|
|
void StyleXULImpl::CopyTo(nsStyleXUL& aDest) const
|
|
{
|
|
nsCRT::memcpy(&aDest, (const nsStyleXUL*)this, sizeof(nsStyleXUL));
|
|
}
|
|
|
|
PRInt32 StyleXULImpl::CalcDifference(const StyleXULImpl& aOther) const
|
|
{
|
|
if (mBoxOrient == aOther.mBoxOrient)
|
|
return NS_STYLE_HINT_NONE;
|
|
return NS_STYLE_HINT_REFLOW;
|
|
}
|
|
|
|
PRUint32 StyleXULImpl::ComputeCRC32(PRUint32 aCrc) const
|
|
{
|
|
PRUint32 crc = aCrc;
|
|
#ifdef COMPUTE_STYLEDATA_CRC
|
|
crc = AccumulateCRC(crc,(const char *)&mBoxOrient,sizeof(mBoxOrient));
|
|
#endif
|
|
return crc;
|
|
}
|
|
|
|
#ifdef XP_MAC
|
|
#pragma mark -
|
|
#endif
|
|
#endif // INCLUDE_XUL
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
#ifdef SHARE_STYLECONTEXTS
|
|
|
|
//========================
|
|
#ifdef DEBUG
|
|
// define this to get stats on the use of the |nsStyleStruct|s inside a |nsStyleContextData|. //XXX pierre
|
|
//#define LOG_STYLE_STRUCTS
|
|
#endif
|
|
|
|
#ifdef LOG_STYLE_STRUCTS
|
|
// StyleFontImpl mFont;
|
|
struct StyleFontImplLog: public StyleFontImpl {
|
|
StyleFontImplLog(const nsFont& aVariableFont, const nsFont& aFixedFont)
|
|
: StyleFontImpl(aVariableFont, aFixedFont),
|
|
mInternalFont(aVariableFont, aFixedFont)
|
|
{}
|
|
void ResetFrom(const nsStyleFont* aParent, nsIPresContext* aPresContext);
|
|
StyleFontImpl mInternalFont;
|
|
bool mSetFromParent;
|
|
};
|
|
|
|
void StyleFontImplLog::ResetFrom(const nsStyleFont* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
StyleFontImpl::ResetFrom(aParent, aPresContext);
|
|
CopyTo(mInternalFont);
|
|
mSetFromParent = (aParent != nsnull);
|
|
}
|
|
|
|
// StyleColorImpl mColor;
|
|
struct StyleColorImplLog: public StyleColorImpl {
|
|
void ResetFrom(const nsStyleColor* aParent, nsIPresContext* aPresContext);
|
|
StyleColorImpl mInternalColor;
|
|
bool mSetFromParent;
|
|
};
|
|
|
|
void StyleColorImplLog::ResetFrom(const nsStyleColor* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
StyleColorImpl::ResetFrom(aParent, aPresContext);
|
|
CopyTo(mInternalColor);
|
|
mSetFromParent = (aParent != nsnull);
|
|
}
|
|
|
|
// StyleListImpl mList;
|
|
struct StyleListImplLog: public StyleListImpl {
|
|
void ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresContext);
|
|
StyleListImpl mInternalList;
|
|
bool mSetFromParent;
|
|
};
|
|
|
|
void StyleListImplLog::ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
StyleListImpl::ResetFrom(aParent, aPresContext);
|
|
CopyTo(mInternalList);
|
|
mSetFromParent = (aParent != nsnull);
|
|
}
|
|
|
|
// StylePositionImpl mPosition;
|
|
struct StylePositionImplLog: public StylePositionImpl {
|
|
void ResetFrom(const nsStylePosition* aParent, nsIPresContext* aPresContext);
|
|
StylePositionImpl mInternalPosition;
|
|
bool mSetFromParent;
|
|
};
|
|
|
|
void StylePositionImplLog::ResetFrom(const nsStylePosition* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
StylePositionImpl::ResetFrom(aParent, aPresContext);
|
|
CopyTo(mInternalPosition);
|
|
mSetFromParent = (aParent != nsnull);
|
|
}
|
|
|
|
// StyleTextImpl mText;
|
|
struct StyleTextImplLog: public StyleTextImpl {
|
|
void ResetFrom(const nsStyleText* aParent, nsIPresContext* aPresContext);
|
|
StyleTextImpl mInternalText;
|
|
bool mSetFromParent;
|
|
};
|
|
|
|
void StyleTextImplLog::ResetFrom(const nsStyleText* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
StyleTextImpl::ResetFrom(aParent, aPresContext);
|
|
CopyTo(mInternalText);
|
|
mSetFromParent = (aParent != nsnull);
|
|
}
|
|
|
|
// StyleDisplayImpl mDisplay;
|
|
struct StyleDisplayImplLog: public StyleDisplayImpl {
|
|
void ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* aPresContext);
|
|
StyleDisplayImpl mInternalDisplay;
|
|
bool mSetFromParent;
|
|
};
|
|
|
|
void StyleDisplayImplLog::ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
StyleDisplayImpl::ResetFrom(aParent, aPresContext);
|
|
CopyTo(mInternalDisplay);
|
|
mSetFromParent = (aParent != nsnull);
|
|
}
|
|
|
|
// StyleTableImpl mTable;
|
|
struct StyleTableImplLog: public StyleTableImpl {
|
|
void ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPresContext);
|
|
StyleTableImpl mInternalTable;
|
|
bool mSetFromParent;
|
|
};
|
|
|
|
void StyleTableImplLog::ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
StyleTableImpl::ResetFrom(aParent, aPresContext);
|
|
CopyTo(mInternalTable);
|
|
mSetFromParent = (aParent != nsnull);
|
|
}
|
|
|
|
// StyleContentImpl mContent;
|
|
struct StyleContentImplLog: public StyleContentImpl {
|
|
void ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPresContext);
|
|
StyleContentImpl mInternalContent;
|
|
bool mSetFromParent;
|
|
};
|
|
|
|
void StyleContentImplLog::ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
StyleContentImpl::ResetFrom(aParent, aPresContext);
|
|
CopyTo(mInternalContent);
|
|
mSetFromParent = (aParent != nsnull);
|
|
}
|
|
|
|
// StyleUserInterfaceImpl mUserInterface;
|
|
struct StyleUserInterfaceImplLog: public StyleUserInterfaceImpl {
|
|
void ResetFrom(const nsStyleUserInterface* aParent, nsIPresContext* aPresContext);
|
|
StyleUserInterfaceImpl mInternalUserInterface;
|
|
bool mSetFromParent;
|
|
};
|
|
|
|
void StyleUserInterfaceImplLog::ResetFrom(const nsStyleUserInterface* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
StyleUserInterfaceImpl::ResetFrom(aParent, aPresContext);
|
|
CopyTo(mInternalUserInterface);
|
|
mSetFromParent = (aParent != nsnull);
|
|
}
|
|
|
|
// StylePrintImpl mPrint;
|
|
struct StylePrintImplLog: public StylePrintImpl {
|
|
void ResetFrom(const nsStylePrint* aParent, nsIPresContext* aPresContext);
|
|
StylePrintImpl mInternalPrint;
|
|
bool mSetFromParent;
|
|
};
|
|
|
|
void StylePrintImplLog::ResetFrom(const nsStylePrint* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
StylePrintImpl::ResetFrom(aParent, aPresContext);
|
|
CopyTo(mInternalPrint);
|
|
mSetFromParent = (aParent != nsnull);
|
|
}
|
|
|
|
// StyleMarginImpl mMargin;
|
|
struct StyleMarginImplLog: public StyleMarginImpl {
|
|
void ResetFrom(const nsStyleMargin* aParent, nsIPresContext* aPresContext);
|
|
StyleMarginImpl mInternalMargin;
|
|
bool mSetFromParent;
|
|
};
|
|
|
|
void StyleMarginImplLog::ResetFrom(const nsStyleMargin* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
StyleMarginImpl::ResetFrom(aParent, aPresContext);
|
|
CopyTo(mInternalMargin);
|
|
mSetFromParent = (aParent != nsnull);
|
|
}
|
|
|
|
// StylePaddingImpl mPadding;
|
|
struct StylePaddingImplLog: public StylePaddingImpl {
|
|
void ResetFrom(const nsStylePadding* aParent, nsIPresContext* aPresContext);
|
|
StylePaddingImpl mInternalPadding;
|
|
bool mSetFromParent;
|
|
};
|
|
|
|
void StylePaddingImplLog::ResetFrom(const nsStylePadding* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
StylePaddingImpl::ResetFrom(aParent, aPresContext);
|
|
CopyTo(mInternalPadding);
|
|
mSetFromParent = (aParent != nsnull);
|
|
}
|
|
|
|
// StyleBorderImpl mBorder;
|
|
struct StyleBorderImplLog: public StyleBorderImpl {
|
|
void ResetFrom(const nsStyleBorder* aParent, nsIPresContext* aPresContext);
|
|
StyleBorderImpl mInternalBorder;
|
|
bool mSetFromParent;
|
|
};
|
|
|
|
void StyleBorderImplLog::ResetFrom(const nsStyleBorder* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
StyleBorderImpl::ResetFrom(aParent, aPresContext);
|
|
CopyTo(mInternalBorder);
|
|
mSetFromParent = (aParent != nsnull);
|
|
}
|
|
|
|
// StyleOutlineImpl mOutline;
|
|
struct StyleOutlineImplLog: public StyleOutlineImpl {
|
|
void ResetFrom(const nsStyleOutline* aParent, nsIPresContext* aPresContext);
|
|
StyleOutlineImpl mInternalOutline;
|
|
bool mSetFromParent;
|
|
};
|
|
|
|
void StyleOutlineImplLog::ResetFrom(const nsStyleOutline* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
StyleOutlineImpl::ResetFrom(aParent, aPresContext);
|
|
CopyTo(mInternalOutline);
|
|
mSetFromParent = (aParent != nsnull);
|
|
}
|
|
|
|
#ifdef INCLUDE_XUL
|
|
// StyleXULImpl mXUL;
|
|
struct StyleXULImplLog: public StyleXULImpl {
|
|
void ResetFrom(const nsStyleXUL* aParent, nsIPresContext* aPresContext);
|
|
StyleXULImpl mInternalXUL;
|
|
bool mSetFromParent;
|
|
};
|
|
|
|
void StyleXULImplLog::ResetFrom(const nsStyleXUL* aParent, nsIPresContext* aPresContext)
|
|
{
|
|
StyleXULImpl::ResetFrom(aParent, aPresContext);
|
|
CopyTo(mInternalXUL);
|
|
mSetFromParent = (aParent != nsnull);
|
|
}
|
|
#endif // INCLUDE_XUL
|
|
|
|
#ifdef XP_MAC
|
|
#pragma mark -
|
|
#endif
|
|
|
|
#endif // LOG_STYLE_STRUCTS
|
|
//========================
|
|
|
|
class nsStyleContextData
|
|
{
|
|
public:
|
|
|
|
friend class StyleContextImpl;
|
|
|
|
void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize);
|
|
|
|
#ifdef LOG_STYLE_STRUCTS
|
|
public:
|
|
#else
|
|
private: // all data and methods private: only friends have access
|
|
#endif
|
|
|
|
static nsStyleContextData *Create(nsIPresContext *aPresContext);
|
|
|
|
nsStyleContextData(nsIPresContext *aPresContext);
|
|
~nsStyleContextData(void);
|
|
|
|
PRUint32 ComputeCRC32(PRUint32 aCrc) const;
|
|
void SetCRC32(void) {
|
|
mCRC = ComputeCRC32(0);
|
|
if (mCRC==STYLEDATA_NO_CRC)
|
|
mCRC = STYLEDATA_DEFAULT_CRC;
|
|
}
|
|
PRUint32 GetCRC32(void) const { return mCRC; }
|
|
|
|
PRUint32 AddRef(void);
|
|
PRUint32 Release(void);
|
|
|
|
// the style data...
|
|
// - StyleContextImpl gets friend-access
|
|
//
|
|
#ifdef LOG_STYLE_STRUCTS
|
|
StyleFontImplLog mFont;
|
|
StyleColorImplLog mColor;
|
|
StyleListImplLog mList;
|
|
StylePositionImplLog mPosition;
|
|
StyleTextImplLog mText;
|
|
StyleDisplayImplLog mDisplay;
|
|
StyleTableImplLog mTable;
|
|
StyleContentImplLog mContent;
|
|
StyleUserInterfaceImplLog mUserInterface;
|
|
StylePrintImplLog mPrint;
|
|
StyleMarginImplLog mMargin;
|
|
StylePaddingImplLog mPadding;
|
|
StyleBorderImplLog mBorder;
|
|
StyleOutlineImplLog mOutline;
|
|
#ifdef INCLUDE_XUL
|
|
StyleXULImplLog mXUL;
|
|
#endif
|
|
#else
|
|
StyleFontImpl mFont;
|
|
StyleColorImpl mColor;
|
|
StyleListImpl mList;
|
|
StylePositionImpl mPosition;
|
|
StyleTextImpl mText;
|
|
StyleDisplayImpl mDisplay;
|
|
StyleTableImpl mTable;
|
|
StyleContentImpl mContent;
|
|
StyleUserInterfaceImpl mUserInterface;
|
|
StylePrintImpl mPrint;
|
|
StyleMarginImpl mMargin;
|
|
StylePaddingImpl mPadding;
|
|
StyleBorderImpl mBorder;
|
|
StyleOutlineImpl mOutline;
|
|
#ifdef INCLUDE_XUL
|
|
StyleXULImpl mXUL;
|
|
#endif
|
|
#endif
|
|
|
|
PRUint32 mRefCnt;
|
|
PRUint32 mCRC;
|
|
|
|
#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));
|
|
#endif
|
|
delete this;
|
|
return 0;
|
|
}
|
|
return mRefCnt;
|
|
}
|
|
|
|
#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)
|
|
{
|
|
}
|
|
|
|
//=========================================================================================================
|
|
|
|
#ifdef LOG_STYLE_STRUCTS //XXX pierre
|
|
|
|
#ifdef XP_MAC
|
|
#include <Events.h>
|
|
static bool MacKeyDown(unsigned char theKey)
|
|
{
|
|
KeyMap map;
|
|
GetKeys(map);
|
|
return ((*((unsigned char *)map + (theKey >> 3)) >> (theKey & 7)) & 1) != 0;
|
|
}
|
|
#endif
|
|
|
|
|
|
static bool IsTimeToDumpStyleStructs()
|
|
{
|
|
bool timeToDump = false;
|
|
#ifdef XP_MAC
|
|
static unsigned long lastTicks = 0;
|
|
if (MacKeyDown(0x3b)) { // control key
|
|
if ((unsigned long)(::TickCount() - lastTicks) > 60) {
|
|
lastTicks = ::TickCount();
|
|
timeToDump = true;
|
|
}
|
|
}
|
|
#endif
|
|
return timeToDump;
|
|
}
|
|
static void LogStyleStructs(nsStyleContextData* aStyleContextData)
|
|
{
|
|
#define max_structs eStyleStruct_Max
|
|
|
|
static unsigned long totalCount = 0;
|
|
static unsigned long defaultStruct[max_structs];
|
|
static unsigned long setFromParent[max_structs];
|
|
|
|
static bool resetCounters = true;
|
|
|
|
if (IsTimeToDumpStyleStructs()) {
|
|
resetCounters = true;
|
|
printf("\n\n\n");
|
|
printf("-------------------------------------------------------------------------------------------------------------\n");
|
|
printf("Count of nsStyleContextData: %ld\n", totalCount);
|
|
printf("-------------------------------------------------------------------------------------------------------------\n");
|
|
printf(" unchanged unchanged%c set-from-parent%c size-of-struct potential-gain-Kb\n", '%', '%');
|
|
unsigned long totalFootprint = 0;
|
|
unsigned long totalPotentialGain = 0;
|
|
for (short i = 0; i < max_structs; i ++) {
|
|
short index = i+1;
|
|
short sizeOfStruct = 0;
|
|
unsigned long footprint = 0;
|
|
unsigned long potentialGain = 0;
|
|
switch (index) {
|
|
case eStyleStruct_Font: printf("eStyleStruct_Font "); sizeOfStruct = sizeof(StyleFontImpl); break;
|
|
case eStyleStruct_Color: printf("eStyleStruct_Color "); sizeOfStruct = sizeof(StyleColorImpl); break;
|
|
case eStyleStruct_List: printf("eStyleStruct_List "); sizeOfStruct = sizeof(StyleListImpl); break;
|
|
case eStyleStruct_Position: printf("eStyleStruct_Position "); sizeOfStruct = sizeof(StylePositionImpl); break;
|
|
case eStyleStruct_Text: printf("eStyleStruct_Text "); sizeOfStruct = sizeof(StyleTextImpl); break;
|
|
case eStyleStruct_Display: printf("eStyleStruct_Display "); sizeOfStruct = sizeof(StyleDisplayImpl); break;
|
|
case eStyleStruct_Table: printf("eStyleStruct_Table "); sizeOfStruct = sizeof(StyleTableImpl); break;
|
|
case eStyleStruct_Content: printf("eStyleStruct_Content "); sizeOfStruct = sizeof(StyleContentImpl); break;
|
|
case eStyleStruct_UserInterface: printf("eStyleStruct_UserInterface "); sizeOfStruct = sizeof(StyleUserInterfaceImpl); break;
|
|
case eStyleStruct_Print: printf("eStyleStruct_Print "); sizeOfStruct = sizeof(StylePrintImpl); break;
|
|
case eStyleStruct_Margin: printf("eStyleStruct_Margin "); sizeOfStruct = sizeof(StyleMarginImpl); break;
|
|
case eStyleStruct_Padding: printf("eStyleStruct_Padding "); sizeOfStruct = sizeof(StylePaddingImpl); break;
|
|
case eStyleStruct_Border: printf("eStyleStruct_Border "); sizeOfStruct = sizeof(StyleBorderImpl); break;
|
|
case eStyleStruct_Outline: printf("eStyleStruct_Outline "); sizeOfStruct = sizeof(StyleOutlineImpl); break;
|
|
#ifdef INCLUDE_XUL
|
|
case eStyleStruct_XUL: printf("eStyleStruct_XUL "); sizeOfStruct = sizeof(StyleXULImpl); break;
|
|
#endif
|
|
}
|
|
short percentDefault = (totalCount == 0 ? 0 : ((100 * defaultStruct[i]) / totalCount));
|
|
short percentFromParent = (defaultStruct[i] == 0 ? 0 : ((100 * setFromParent[i]) / defaultStruct[i]));
|
|
|
|
footprint = totalCount * sizeOfStruct;
|
|
totalFootprint += footprint;
|
|
|
|
potentialGain = defaultStruct[i] * sizeOfStruct;
|
|
totalPotentialGain += potentialGain;
|
|
|
|
printf(" %7ld %3d %3d %5d %5d\n", defaultStruct[i], percentDefault, percentFromParent, sizeOfStruct, potentialGain / 1024);
|
|
}
|
|
printf("-------------------------------------------------------------------------------------------------------------\n");
|
|
printf("Current footprint: %4ld Kb\n", totalFootprint / 1024);
|
|
printf("Potential gain: %4ld Kb (or %d%c)\n", totalPotentialGain / 1024, totalPotentialGain*100/totalFootprint, '%');
|
|
printf("Would remain: %4ld Kb\n", (totalFootprint - totalPotentialGain) / 1024);
|
|
printf("-------------------------------------------------------------------------------------------------------------\n");
|
|
printf("These stats come from the nsStyleContextData structures that have been deleted since the last output.\n");
|
|
printf("To get the stats for a particular page: load page, dump stats, load 'about:blank', dump stats again.\n");
|
|
printf("-------------------------------------------------------------------------------------------------------------\n");
|
|
printf("\n\n\n");
|
|
}
|
|
|
|
if (resetCounters) {
|
|
resetCounters = false;
|
|
totalCount = 0;
|
|
for (short i = 0; i < max_structs; i ++) {
|
|
defaultStruct[i] = 0L;
|
|
setFromParent[i] = 0L;
|
|
}
|
|
}
|
|
|
|
if (!aStyleContextData) {
|
|
printf ("*** aStyleContextData is nil\n");
|
|
return;
|
|
}
|
|
|
|
totalCount++;
|
|
for (short i = 0; i < max_structs; i ++) {
|
|
short index = i+1;
|
|
switch (index) {
|
|
case eStyleStruct_Font:
|
|
if (aStyleContextData->mFont.CalcDifference(aStyleContextData->mFont.mInternalFont) == NS_STYLE_HINT_NONE) {
|
|
defaultStruct[i]++;
|
|
if (aStyleContextData->mFont.mSetFromParent)
|
|
setFromParent[i]++;
|
|
}
|
|
break;
|
|
case eStyleStruct_Color:
|
|
if (aStyleContextData->mColor.CalcDifference(aStyleContextData->mColor.mInternalColor) == NS_STYLE_HINT_NONE) {
|
|
defaultStruct[i]++;
|
|
if (aStyleContextData->mColor.mSetFromParent)
|
|
setFromParent[i]++;
|
|
}
|
|
break;
|
|
case eStyleStruct_List:
|
|
if (aStyleContextData->mList.CalcDifference(aStyleContextData->mList.mInternalList) == NS_STYLE_HINT_NONE) {
|
|
defaultStruct[i]++;
|
|
if (aStyleContextData->mList.mSetFromParent)
|
|
setFromParent[i]++;
|
|
}
|
|
break;
|
|
case eStyleStruct_Position:
|
|
if (aStyleContextData->mPosition.CalcDifference(aStyleContextData->mPosition.mInternalPosition) == NS_STYLE_HINT_NONE) {
|
|
defaultStruct[i]++;
|
|
if (aStyleContextData->mPosition.mSetFromParent)
|
|
setFromParent[i]++;
|
|
}
|
|
break;
|
|
case eStyleStruct_Text:
|
|
if (aStyleContextData->mText.CalcDifference(aStyleContextData->mText.mInternalText) == NS_STYLE_HINT_NONE) {
|
|
defaultStruct[i]++;
|
|
if (aStyleContextData->mText.mSetFromParent)
|
|
setFromParent[i]++;
|
|
}
|
|
break;
|
|
case eStyleStruct_Display:
|
|
if (aStyleContextData->mDisplay.CalcDifference(aStyleContextData->mDisplay.mInternalDisplay) == NS_STYLE_HINT_NONE) {
|
|
defaultStruct[i]++;
|
|
if (aStyleContextData->mDisplay.mSetFromParent)
|
|
setFromParent[i]++;
|
|
}
|
|
break;
|
|
case eStyleStruct_Table:
|
|
if (aStyleContextData->mTable.CalcDifference(aStyleContextData->mTable.mInternalTable) == NS_STYLE_HINT_NONE) {
|
|
defaultStruct[i]++;
|
|
if (aStyleContextData->mTable.mSetFromParent)
|
|
setFromParent[i]++;
|
|
}
|
|
break;
|
|
case eStyleStruct_Content:
|
|
if (aStyleContextData->mContent.CalcDifference(aStyleContextData->mContent.mInternalContent) == NS_STYLE_HINT_NONE) {
|
|
defaultStruct[i]++;
|
|
if (aStyleContextData->mContent.mSetFromParent)
|
|
setFromParent[i]++;
|
|
}
|
|
break;
|
|
case eStyleStruct_UserInterface:
|
|
if (aStyleContextData->mUserInterface.CalcDifference(aStyleContextData->mUserInterface.mInternalUserInterface) == NS_STYLE_HINT_NONE) {
|
|
defaultStruct[i]++;
|
|
if (aStyleContextData->mUserInterface.mSetFromParent)
|
|
setFromParent[i]++;
|
|
}
|
|
break;
|
|
case eStyleStruct_Print:
|
|
if (aStyleContextData->mPrint.CalcDifference(aStyleContextData->mPrint.mInternalPrint) == NS_STYLE_HINT_NONE) {
|
|
defaultStruct[i]++;
|
|
if (aStyleContextData->mPrint.mSetFromParent)
|
|
setFromParent[i]++;
|
|
}
|
|
break;
|
|
case eStyleStruct_Margin:
|
|
if (aStyleContextData->mMargin.CalcDifference(aStyleContextData->mMargin.mInternalMargin) == NS_STYLE_HINT_NONE) {
|
|
defaultStruct[i]++;
|
|
if (aStyleContextData->mMargin.mSetFromParent)
|
|
setFromParent[i]++;
|
|
}
|
|
break;
|
|
case eStyleStruct_Padding:
|
|
if (aStyleContextData->mPadding.CalcDifference(aStyleContextData->mPadding.mInternalPadding) == NS_STYLE_HINT_NONE) {
|
|
defaultStruct[i]++;
|
|
if (aStyleContextData->mPadding.mSetFromParent)
|
|
setFromParent[i]++;
|
|
}
|
|
break;
|
|
case eStyleStruct_Border:
|
|
if (aStyleContextData->mBorder.CalcDifference(aStyleContextData->mBorder.mInternalBorder) == NS_STYLE_HINT_NONE) {
|
|
defaultStruct[i]++;
|
|
if (aStyleContextData->mBorder.mSetFromParent)
|
|
setFromParent[i]++;
|
|
}
|
|
break;
|
|
case eStyleStruct_Outline:
|
|
if (aStyleContextData->mOutline.CalcDifference(aStyleContextData->mOutline.mInternalOutline) == NS_STYLE_HINT_NONE) {
|
|
defaultStruct[i]++;
|
|
if (aStyleContextData->mOutline.mSetFromParent)
|
|
setFromParent[i]++;
|
|
}
|
|
break;
|
|
#ifdef INCLUDE_XUL
|
|
case eStyleStruct_XUL:
|
|
if (aStyleContextData->mXUL.CalcDifference(aStyleContextData->mXUL.mInternalXUL) == NS_STYLE_HINT_NONE) {
|
|
defaultStruct[i]++;
|
|
if (aStyleContextData->mXUL.mSetFromParent)
|
|
setFromParent[i]++;
|
|
}
|
|
break;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
static short inCount = 0;
|
|
static short outCount = 0;
|
|
if (inCount++ % 1000 == 0) {
|
|
switch (outCount++) {
|
|
case 0: printf("still logging"); break;
|
|
case 20: printf("\n"); outCount = 0; break;
|
|
default: printf("."); fflush(stdout); break;
|
|
}
|
|
}
|
|
}
|
|
#endif // LOG_STYLE_STRUCTS
|
|
|
|
//=========================================================================================================
|
|
|
|
nsStyleContextData::~nsStyleContextData(void)
|
|
{
|
|
NS_ASSERTION(0 == mRefCnt, "RefCount error in ~nsStyleContextData");
|
|
// debug here...
|
|
#ifdef LOG_STYLE_STRUCTS
|
|
LogStyleStructs(this);
|
|
#endif
|
|
}
|
|
|
|
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 = 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);
|
|
crc = mMargin.ComputeCRC32(crc);
|
|
crc = mPadding.ComputeCRC32(crc);
|
|
crc = mBorder.ComputeCRC32(crc);
|
|
crc = mOutline.ComputeCRC32(crc);
|
|
#ifdef INCLUDE_XUL
|
|
crc = mXUL.ComputeCRC32(crc);
|
|
#endif
|
|
#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
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
class StyleContextImpl : public nsIStyleContext,
|
|
protected nsIMutableStyleContext { // you can't QI to nsIMutableStyleContext
|
|
public:
|
|
StyleContextImpl(nsIStyleContext* aParent, nsIAtom* aPseudoTag,
|
|
nsISupportsArray* aRules,
|
|
nsIPresContext* aPresContext);
|
|
virtual ~StyleContextImpl();
|
|
|
|
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
virtual nsIStyleContext* GetParent(void) const;
|
|
virtual nsISupportsArray* GetStyleRules(void) const;
|
|
virtual PRInt32 GetStyleRuleCount(void) const;
|
|
NS_IMETHOD GetPseudoType(nsIAtom*& aPseudoTag) const;
|
|
|
|
NS_IMETHOD FindChildWithRules(const nsIAtom* aPseudoTag, nsISupportsArray* aRules,
|
|
nsIStyleContext*& aResult);
|
|
|
|
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);
|
|
|
|
virtual void ForceUnique(void);
|
|
virtual void RecalcAutomaticData(nsIPresContext* aPresContext);
|
|
virtual void CalcBorderPaddingFor(const nsIFrame* aFrame, nsMargin& aBorderPadding) const;
|
|
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
|
|
|
|
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);
|
|
void RemoveChild(StyleContextImpl* aChild);
|
|
|
|
StyleContextImpl* mParent;
|
|
StyleContextImpl* mChild;
|
|
StyleContextImpl* mEmptyChild;
|
|
StyleContextImpl* mPrevSibling;
|
|
StyleContextImpl* mNextSibling;
|
|
|
|
nsIAtom* mPseudoTag;
|
|
|
|
PRUint32 mRuleHash;
|
|
nsISupportsArray* mRules;
|
|
PRInt16 mDataCode;
|
|
|
|
#ifdef SHARE_STYLECONTEXTS
|
|
|
|
nsStyleContextData* mStyleData;
|
|
|
|
#else
|
|
|
|
// the style data...
|
|
StyleFontImpl mFont;
|
|
StyleColorImpl mColor;
|
|
StyleListImpl mList;
|
|
StylePositionImpl mPosition;
|
|
StyleTextImpl mText;
|
|
StyleDisplayImpl mDisplay;
|
|
StyleTableImpl mTable;
|
|
StyleContentImpl mContent;
|
|
StyleUserInterfaceImpl mUserInterface;
|
|
StylePrintImpl mPrint;
|
|
StyleMarginImpl mMargin;
|
|
StylePaddingImpl mPadding;
|
|
StyleBorderImpl mBorder;
|
|
StyleOutlineImpl mOutline;
|
|
#ifdef INCLUDE_XUL
|
|
StyleXULImpl mXUL;
|
|
#endif
|
|
|
|
#endif // #ifdef SHARE_STYLECONTEXTS
|
|
|
|
// make sure we have valid style data
|
|
nsresult EnsureStyleData(nsIPresContext* aPresContext);
|
|
nsresult HaveStyleData(void) const;
|
|
|
|
nsCOMPtr<nsIStyleSet> mStyleSet;
|
|
};
|
|
|
|
static PRInt32 gLastDataCode;
|
|
|
|
static PRBool HashStyleRule(nsISupports* aRule, void* aData)
|
|
{
|
|
*((PRUint32*)aData) ^= PRUint32(aRule);
|
|
return PR_TRUE;
|
|
}
|
|
|
|
#ifdef XP_MAC
|
|
#pragma mark -
|
|
#endif
|
|
|
|
StyleContextImpl::StyleContextImpl(nsIStyleContext* aParent,
|
|
nsIAtom* aPseudoTag,
|
|
nsISupportsArray* aRules,
|
|
nsIPresContext* aPresContext)
|
|
: mParent((StyleContextImpl*)aParent),
|
|
mChild(nsnull),
|
|
mEmptyChild(nsnull),
|
|
mPseudoTag(aPseudoTag),
|
|
mRules(aRules),
|
|
mDataCode(-1),
|
|
#ifdef SHARE_STYLECONTEXTS
|
|
mStyleData(nsnull)
|
|
#else
|
|
mFont(aPresContext->GetDefaultFontDeprecated(), aPresContext->GetDefaultFixedFontDeprecated()),
|
|
mColor(),
|
|
mSpacing(),
|
|
mList(),
|
|
mPosition(),
|
|
mText(),
|
|
mDisplay(),
|
|
mTable(),
|
|
mContent(),
|
|
mUserInterface(),
|
|
#ifdef INCLUDE_XUL
|
|
mXUL(),
|
|
#endif
|
|
mPrint()
|
|
#endif
|
|
{
|
|
NS_INIT_REFCNT();
|
|
NS_IF_ADDREF(mPseudoTag);
|
|
NS_IF_ADDREF(mRules);
|
|
|
|
mNextSibling = this;
|
|
mPrevSibling = this;
|
|
if (nsnull != mParent) {
|
|
NS_ADDREF(mParent);
|
|
mParent->AppendChild(this);
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
StyleContextImpl::~StyleContextImpl()
|
|
{
|
|
NS_ASSERTION((nsnull == mChild) && (nsnull == mEmptyChild), "destructing context with children");
|
|
|
|
if (mParent) {
|
|
mParent->RemoveChild(this);
|
|
NS_RELEASE(mParent);
|
|
}
|
|
|
|
NS_IF_RELEASE(mPseudoTag);
|
|
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
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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 {
|
|
if (nsnull == mChild) {
|
|
mChild = aChild;
|
|
}
|
|
else {
|
|
aChild->mNextSibling = mChild;
|
|
aChild->mPrevSibling = mChild->mPrevSibling;
|
|
mChild->mPrevSibling->mNextSibling = aChild;
|
|
mChild->mPrevSibling = aChild;
|
|
}
|
|
}
|
|
}
|
|
|
|
void StyleContextImpl::RemoveChild(StyleContextImpl* aChild)
|
|
{
|
|
NS_ASSERTION((nsnull != aChild) && (this == aChild->mParent), "bad argument");
|
|
|
|
if ((nsnull == aChild) || (this != aChild->mParent)) {
|
|
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;
|
|
}
|
|
}
|
|
else { // isn't empty
|
|
if (aChild->mPrevSibling != aChild) { // has siblings
|
|
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;
|
|
}
|
|
|
|
nsISupportsArray* StyleContextImpl::GetStyleRules(void) const
|
|
{
|
|
nsISupportsArray* result = mRules;
|
|
NS_IF_ADDREF(result);
|
|
return result;
|
|
}
|
|
|
|
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;
|
|
}
|
|
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;
|
|
|
|
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;
|
|
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);
|
|
}
|
|
}
|
|
else if (nsnull != mChild) {
|
|
PRUint32 hash = 0;
|
|
aRules->EnumerateForwards(HashStyleRule, &hash);
|
|
child = mChild;
|
|
do {
|
|
PRUint32 cnt;
|
|
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) {
|
|
if (child->mRules->Equals(aRules)) {
|
|
aResult = child;
|
|
break;
|
|
}
|
|
}
|
|
child = child->mNextSibling;
|
|
} while (child != mChild);
|
|
}
|
|
}
|
|
NS_IF_ADDREF(aResult);
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
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;
|
|
}
|
|
else {
|
|
if ((nsnull != mRules) && (nsnull != other->mRules)) {
|
|
if (mRuleHash == other->mRuleHash) {
|
|
result = mRules->Equals(other->mRules);
|
|
}
|
|
else {
|
|
result = PR_FALSE;
|
|
}
|
|
}
|
|
else {
|
|
result = PRBool((nsnull == mRules) && (nsnull == other->mRules));
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
PRUint32 StyleContextImpl::HashValue(void) const
|
|
{
|
|
return mRuleHash;
|
|
}
|
|
|
|
//=========================================================================================================
|
|
#ifdef DEBUG
|
|
// define this to get statistics on the number of calls
|
|
// to GetStyleData() and their depth in the Style tree.
|
|
//#define LOG_GET_STYLE_DATA_CALLS //XXX pierre
|
|
#endif
|
|
|
|
#ifdef LOG_GET_STYLE_DATA_CALLS
|
|
|
|
#ifdef XP_MAC
|
|
#include <Events.h>
|
|
#include <Timer.h>
|
|
static bool MacKeyDown(unsigned char theKey)
|
|
{
|
|
KeyMap map;
|
|
GetKeys(map);
|
|
return ((*((unsigned char *)map + (theKey >> 3)) >> (theKey & 7)) & 1) != 0;
|
|
}
|
|
#endif
|
|
|
|
|
|
static bool IsTimeToDumpGetStyleDataCalls()
|
|
{
|
|
bool timeToDump = false;
|
|
#ifdef XP_MAC
|
|
static unsigned long lastTicks = 0;
|
|
if (MacKeyDown(0x3b)) { // control key
|
|
if ((unsigned long)(::TickCount() - lastTicks) > 60) {
|
|
lastTicks = ::TickCount();
|
|
timeToDump = true;
|
|
}
|
|
}
|
|
#endif
|
|
return timeToDump;
|
|
}
|
|
|
|
enum LogCallType {
|
|
logCallType_GetStyleData = 0,
|
|
logCallType_GetMutableStyleData,
|
|
logCallType_GetStyle,
|
|
|
|
logCallType_Max
|
|
};
|
|
|
|
static void LogGetStyleDataCall(nsStyleStructID aSID, LogCallType aLogCallType, nsIStyleContext* aStyleContext, bool aEnteringFunction)
|
|
{
|
|
#define max_structs (eStyleStruct_Max + 1)
|
|
#define small_depth_threshold 8
|
|
|
|
static unsigned long calls[max_structs*logCallType_Max];
|
|
static unsigned long callspercent[max_structs*logCallType_Max];
|
|
static unsigned long depth[max_structs*logCallType_Max];
|
|
static unsigned long maxdepth[max_structs*logCallType_Max];
|
|
static unsigned long smalldepth[max_structs*logCallType_Max];
|
|
static unsigned long microsecs[logCallType_Max];
|
|
static unsigned long totalMicrosecs;
|
|
static UnsignedWide startMicrosecs;
|
|
static UnsignedWide endMicrosecs;
|
|
|
|
if (!aEnteringFunction) {
|
|
::Microseconds(&endMicrosecs);
|
|
totalMicrosecs += endMicrosecs.lo - startMicrosecs.lo;
|
|
microsecs[aLogCallType] += endMicrosecs.lo - startMicrosecs.lo;
|
|
return;
|
|
}
|
|
|
|
|
|
static bool resetCounters = true;
|
|
|
|
if (IsTimeToDumpGetStyleDataCalls()) {
|
|
resetCounters = true;
|
|
|
|
unsigned long totalCalls;
|
|
unsigned long totalMaxdepth;
|
|
unsigned long totalDepth;
|
|
for (short i = 0; i < (max_structs*logCallType_Max); i ++) {
|
|
|
|
if (i%max_structs == 0) {
|
|
switch (i/max_structs) {
|
|
case 0:
|
|
printf("\n\n\n");
|
|
printf("----GetStyleData--------------------------------------------------------------------------\n");
|
|
printf(" calls calls%c max depth avg depth (depth<%d)%\n", '%', small_depth_threshold);
|
|
break;
|
|
case 1:
|
|
printf("----GetMutableStyleData-------------------------------------------------------------------\n");
|
|
printf(" calls calls%c max depth avg depth (depth<%d)%\n", '%', small_depth_threshold);
|
|
break;
|
|
case 2:
|
|
printf("----GetStyle------------------------------------------------------------------------------\n");
|
|
printf(" calls calls%c max depth avg depth (depth<%d)%\n", '%', small_depth_threshold);
|
|
break;
|
|
}
|
|
|
|
totalCalls = totalMaxdepth = totalDepth = 0;
|
|
for (short j = i; j < i + max_structs; j++) {
|
|
totalCalls += calls[j];
|
|
totalDepth += depth[j];
|
|
if (totalMaxdepth < maxdepth[j]) {
|
|
totalMaxdepth = maxdepth[j];
|
|
}
|
|
}
|
|
}
|
|
|
|
switch (i%max_structs + 1) {
|
|
case eStyleStruct_Font: printf("eStyleStruct_Font "); break;
|
|
case eStyleStruct_Color: printf("eStyleStruct_Color "); break;
|
|
case eStyleStruct_List: printf("eStyleStruct_List "); break;
|
|
case eStyleStruct_Position: printf("eStyleStruct_Position "); break;
|
|
case eStyleStruct_Text: printf("eStyleStruct_Text "); break;
|
|
case eStyleStruct_Display: printf("eStyleStruct_Display "); break;
|
|
case eStyleStruct_Table: printf("eStyleStruct_Table "); break;
|
|
case eStyleStruct_Content: printf("eStyleStruct_Content "); break;
|
|
case eStyleStruct_UserInterface: printf("eStyleStruct_UserInterface "); break;
|
|
case eStyleStruct_Print: printf("eStyleStruct_Print "); break;
|
|
case eStyleStruct_Margin: printf("eStyleStruct_Margin "); break;
|
|
case eStyleStruct_Padding: printf("eStyleStruct_Padding "); break;
|
|
case eStyleStruct_Border: printf("eStyleStruct_Border "); break;
|
|
case eStyleStruct_Outline: printf("eStyleStruct_Outline "); break;
|
|
case eStyleStruct_BorderPaddingShortcut: printf("BorderPaddingShortcut "); break;
|
|
#ifdef INCLUDE_XUL
|
|
case eStyleStruct_XUL: printf("eStyleStruct_XUL "); break;
|
|
#endif
|
|
}
|
|
short percent = 100*calls[i]/totalCalls;
|
|
short avdepth = calls[i] == 0 ? 0 : round(float(depth[i])/float(calls[i]));
|
|
short smdepth = 100*smalldepth[i]/calls[i];
|
|
if (percent == 0) {
|
|
printf(" %7ld - %3ld %3d %3d\n", calls[i], maxdepth[i], avdepth, smdepth);
|
|
}
|
|
else {
|
|
printf(" %7ld %2ld %3ld %3d %3d\n", calls[i], percent, maxdepth[i], avdepth, smdepth);
|
|
}
|
|
|
|
if (i%max_structs + 1 == max_structs) {
|
|
short totaldepth = totalCalls == 0 ? 0 : round(float(totalDepth)/float(totalCalls));
|
|
printf("TOTAL ");
|
|
printf(" %7ld 100 %3ld %3d %ld ms\n", totalCalls, totalMaxdepth, totaldepth, microsecs[i/max_structs]/1000);
|
|
}
|
|
|
|
}
|
|
printf("------------------------------------------------------------------------------------------\n");
|
|
printf("TOTAL time = %ld microsecs (= %ld ms)\n", totalMicrosecs, totalMicrosecs/1000);
|
|
printf("------------------------------------------------------------------------------------------\n\n\n");
|
|
}
|
|
|
|
if (resetCounters) {
|
|
resetCounters = false;
|
|
totalMicrosecs = 0;
|
|
for (short i = 0; i < logCallType_Max; i ++) {
|
|
microsecs[i] = 0L;
|
|
}
|
|
for (short i = 0; i < (max_structs*logCallType_Max); i ++) {
|
|
calls[i] = 0L;
|
|
depth[i] = 0L;
|
|
maxdepth[i] = 0L;
|
|
smalldepth[i] = 0L;
|
|
}
|
|
}
|
|
|
|
short index = aSID - 1;
|
|
index += max_structs * aLogCallType;
|
|
|
|
calls[index]++;
|
|
|
|
unsigned long curdepth = 0;
|
|
nsCOMPtr<nsIStyleContext> childContext;
|
|
nsCOMPtr<nsIStyleContext> parentContext;
|
|
childContext = aStyleContext;
|
|
parentContext = getter_AddRefs(childContext->GetParent());
|
|
while (parentContext != nsnull) {
|
|
curdepth++;
|
|
parentContext = getter_AddRefs(childContext->GetParent());
|
|
if (parentContext == childContext) {
|
|
break;
|
|
}
|
|
childContext = parentContext;
|
|
}
|
|
depth[index] += curdepth;
|
|
if (maxdepth[index] < curdepth) {
|
|
maxdepth[index] = curdepth;
|
|
}
|
|
if (curdepth <= small_depth_threshold) {
|
|
smalldepth[index]++;
|
|
}
|
|
|
|
static short inCount = 0;
|
|
static short outCount = 0;
|
|
if (inCount++ % 1000 == 0) {
|
|
switch (outCount++) {
|
|
case 0: printf("still logging"); break;
|
|
case 20: printf("\n"); outCount = 0; break;
|
|
default: printf("."); fflush(stdout); break;
|
|
}
|
|
}
|
|
::Microseconds(&startMicrosecs);
|
|
}
|
|
#endif // LOG_GET_STYLE_DATA_CALLS
|
|
//=========================================================================================================
|
|
|
|
const nsStyleStruct* StyleContextImpl::GetStyleData(nsStyleStructID aSID)
|
|
{
|
|
#ifdef LOG_GET_STYLE_DATA_CALLS
|
|
LogGetStyleDataCall(aSID, logCallType_GetStyleData, this, true);
|
|
#endif
|
|
|
|
nsStyleStruct* result = nsnull;
|
|
|
|
switch (aSID) {
|
|
case eStyleStruct_Font:
|
|
result = & GETSCDATA(Font);
|
|
break;
|
|
case eStyleStruct_Color:
|
|
result = & GETSCDATA(Color);
|
|
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);
|
|
break;
|
|
case eStyleStruct_Print:
|
|
result = & GETSCDATA(Print);
|
|
break;
|
|
case eStyleStruct_Margin:
|
|
result = & GETSCDATA(Margin);
|
|
break;
|
|
case eStyleStruct_Padding:
|
|
result = & GETSCDATA(Padding);
|
|
break;
|
|
case eStyleStruct_Border:
|
|
result = & GETSCDATA(Border);
|
|
break;
|
|
case eStyleStruct_Outline:
|
|
result = & GETSCDATA(Outline);
|
|
break;
|
|
#ifdef INCLUDE_XUL
|
|
case eStyleStruct_XUL:
|
|
result = & GETSCDATA(XUL);
|
|
break;
|
|
#endif
|
|
default:
|
|
NS_ERROR("Invalid style struct id");
|
|
break;
|
|
}
|
|
#ifdef LOG_GET_STYLE_DATA_CALLS
|
|
LogGetStyleDataCall(aSID, logCallType_GetStyleData, this, false);
|
|
#endif
|
|
|
|
return result;
|
|
}
|
|
|
|
nsStyleStruct* StyleContextImpl::GetMutableStyleData(nsStyleStructID aSID)
|
|
{
|
|
#ifdef LOG_GET_STYLE_DATA_CALLS
|
|
LogGetStyleDataCall(aSID, logCallType_GetMutableStyleData, this, true);
|
|
#endif
|
|
|
|
nsStyleStruct* result = nsnull;
|
|
|
|
switch (aSID) {
|
|
case eStyleStruct_Font:
|
|
result = & GETSCDATA(Font);
|
|
break;
|
|
case eStyleStruct_Color:
|
|
result = & GETSCDATA(Color);
|
|
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);
|
|
break;
|
|
case eStyleStruct_Print:
|
|
result = & GETSCDATA(Print);
|
|
break;
|
|
case eStyleStruct_Margin:
|
|
result = & GETSCDATA(Margin);
|
|
break;
|
|
case eStyleStruct_Padding:
|
|
result = & GETSCDATA(Padding);
|
|
break;
|
|
case eStyleStruct_Border:
|
|
result = & GETSCDATA(Border);
|
|
break;
|
|
case eStyleStruct_Outline:
|
|
result = & GETSCDATA(Outline);
|
|
break;
|
|
#ifdef INCLUDE_XUL
|
|
case eStyleStruct_XUL:
|
|
result = & GETSCDATA(XUL);
|
|
break;
|
|
#endif
|
|
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
|
|
}
|
|
}
|
|
#ifdef LOG_GET_STYLE_DATA_CALLS
|
|
LogGetStyleDataCall(aSID, logCallType_GetMutableStyleData, this, false);
|
|
#endif
|
|
|
|
return result;
|
|
}
|
|
|
|
void StyleContextImpl::CalcBorderPaddingFor(const nsIFrame* aFrame, nsMargin& aBorderPadding) const
|
|
{
|
|
nsMargin border, padding;
|
|
if (!GETSCDATA(Border).GetBorder(border)) {
|
|
GETSCDATA(Border).CalcBorderFor(aFrame, border);
|
|
}
|
|
if (!GETSCDATA(Padding).GetPadding(padding)) {
|
|
GETSCDATA(Padding).CalcPaddingFor(aFrame, padding);
|
|
}
|
|
aBorderPadding = border + padding;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
StyleContextImpl::GetStyle(nsStyleStructID aSID, nsStyleStruct& aStruct) const
|
|
{
|
|
#ifdef LOG_GET_STYLE_DATA_CALLS
|
|
LogGetStyleDataCall(aSID, logCallType_GetStyle, (nsIStyleContext*)this, true);
|
|
#endif
|
|
|
|
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_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;
|
|
case eStyleStruct_Margin:
|
|
GETSCDATA(Margin).CopyTo((nsStyleMargin&)aStruct);
|
|
break;
|
|
case eStyleStruct_Padding:
|
|
GETSCDATA(Padding).CopyTo((nsStylePadding&)aStruct);
|
|
break;
|
|
case eStyleStruct_Border:
|
|
GETSCDATA(Border).CopyTo((nsStyleBorder&)aStruct);
|
|
break;
|
|
case eStyleStruct_Outline:
|
|
GETSCDATA(Outline).CopyTo((nsStyleOutline&)aStruct);
|
|
break;
|
|
#ifdef INCLUDE_XUL
|
|
case eStyleStruct_XUL:
|
|
GETSCDATA(XUL).CopyTo((nsStyleXUL&)aStruct);
|
|
break;
|
|
#endif
|
|
case eStyleStruct_BorderPaddingShortcut: {
|
|
nsMargin border, padding;
|
|
if (GETSCDATA(Border).GetBorder(border)) {
|
|
if (GETSCDATA(Padding).GetPadding(padding)) {
|
|
border += padding;
|
|
((nsStyleBorderPadding&)aStruct).SetBorderPadding(border);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
NS_ERROR("Invalid style struct id");
|
|
result = NS_ERROR_INVALID_ARG;
|
|
break;
|
|
}
|
|
#ifdef LOG_GET_STYLE_DATA_CALLS
|
|
LogGetStyleDataCall(aSID, logCallType_GetStyle, (nsIStyleContext*)this, false);
|
|
#endif
|
|
|
|
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_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;
|
|
case eStyleStruct_Margin:
|
|
GETSCDATA(Margin).SetFrom((const nsStyleMargin&)aStruct);
|
|
break;
|
|
case eStyleStruct_Padding:
|
|
GETSCDATA(Padding).SetFrom((const nsStylePadding&)aStruct);
|
|
break;
|
|
case eStyleStruct_Border:
|
|
GETSCDATA(Border).SetFrom((const nsStyleBorder&)aStruct);
|
|
break;
|
|
case eStyleStruct_Outline:
|
|
GETSCDATA(Outline).SetFrom((const nsStyleOutline&)aStruct);
|
|
break;
|
|
#ifdef INCLUDE_XUL
|
|
case eStyleStruct_XUL:
|
|
GETSCDATA(XUL).SetFrom((const nsStyleXUL&)aStruct);
|
|
break;
|
|
#endif
|
|
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;
|
|
rule->MapStyleInto(data->mStyleContext, data->mPresContext);
|
|
return PR_TRUE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
StyleContextImpl::RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse)
|
|
{
|
|
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(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);
|
|
GETSCDATA(Margin).ResetFrom(&(mParent->GETSCDATA(Margin)), aPresContext);
|
|
GETSCDATA(Padding).ResetFrom(&(mParent->GETSCDATA(Padding)), aPresContext);
|
|
GETSCDATA(Border).ResetFrom(&(mParent->GETSCDATA(Border)), aPresContext);
|
|
GETSCDATA(Outline).ResetFrom(&(mParent->GETSCDATA(Outline)), aPresContext);
|
|
#ifdef INCLUDE_XUL
|
|
GETSCDATA(XUL).ResetFrom(&(mParent->GETSCDATA(XUL)), aPresContext);
|
|
#endif
|
|
}
|
|
else {
|
|
GETSCDATA(Font).ResetFrom(nsnull, aPresContext);
|
|
GETSCDATA(Color).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);
|
|
GETSCDATA(Margin).ResetFrom(nsnull, aPresContext);
|
|
GETSCDATA(Padding).ResetFrom(nsnull, aPresContext);
|
|
GETSCDATA(Border).ResetFrom(nsnull, aPresContext);
|
|
GETSCDATA(Outline).ResetFrom(nsnull, aPresContext);
|
|
#ifdef INCLUDE_XUL
|
|
GETSCDATA(XUL).ResetFrom(nsnull, aPresContext);
|
|
#endif
|
|
}
|
|
|
|
PRUint32 cnt = 0;
|
|
if (mRules) {
|
|
nsresult rv = mRules->Count(&cnt);
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Count failed");
|
|
}
|
|
if (0 < cnt) {
|
|
MapStyleData data(this, aPresContext);
|
|
mRules->EnumerateForwards(MapStyleRuleFont, &data);
|
|
if (GETSCDATA(Font).mFlags & NS_STYLE_FONT_USE_FIXED) {
|
|
GETSCDATA(Font).mFont = GETSCDATA(Font).mFixedFont;
|
|
}
|
|
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)) &&
|
|
(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(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(Margin).ResetFrom(nsnull, aPresContext);
|
|
GETSCDATA(Padding).ResetFrom(nsnull, aPresContext);
|
|
GETSCDATA(Border).ResetFrom(nsnull, aPresContext);
|
|
GETSCDATA(Outline).ResetFrom(nsnull, aPresContext);
|
|
#ifdef INCLUDE_XUL
|
|
GETSCDATA(XUL).ResetFrom(nsnull, aPresContext);
|
|
#endif
|
|
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;
|
|
}
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
void StyleContextImpl::ForceUnique(void)
|
|
{
|
|
if (mDataCode <= 0) {
|
|
mDataCode = ++gLastDataCode;
|
|
}
|
|
}
|
|
|
|
void StyleContextImpl::RecalcAutomaticData(nsIPresContext* aPresContext)
|
|
{
|
|
if (NS_FAILED(EnsureStyleData(aPresContext))) {
|
|
return /*NS_FAILURE*/;
|
|
}
|
|
GETSCDATA(Margin).RecalcData();
|
|
GETSCDATA(Padding).RecalcData();
|
|
GETSCDATA(Border).RecalcData(GETSCDATA(Color).mColor);
|
|
GETSCDATA(Outline).RecalcData();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
StyleContextImpl::CalcStyleDifference(nsIStyleContext* aOther, PRInt32& aHint,PRBool aStopAtFirstDifference /*= PR_FALSE*/) const
|
|
{
|
|
if (NS_FAILED(HaveStyleData())) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
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;
|
|
if (aHint < NS_STYLE_HINT_MAX) {
|
|
hint = GETSCDATA(Color).CalcDifference(other->GETSCDATA(Color));
|
|
if (aHint < hint) {
|
|
aHint = hint;
|
|
}
|
|
}
|
|
if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK;
|
|
if (aHint < NS_STYLE_HINT_MAX) {
|
|
hint = GETSCDATA(Margin).CalcDifference(other->GETSCDATA(Margin));
|
|
if (aHint < hint) {
|
|
aHint = hint;
|
|
}
|
|
}
|
|
if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK;
|
|
if (aHint < NS_STYLE_HINT_MAX) {
|
|
hint = GETSCDATA(Padding).CalcDifference(other->GETSCDATA(Padding));
|
|
if (aHint < hint) {
|
|
aHint = hint;
|
|
}
|
|
}
|
|
if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK;
|
|
if (aHint < NS_STYLE_HINT_MAX) {
|
|
hint = GETSCDATA(Border).CalcDifference(other->GETSCDATA(Border));
|
|
if (aHint < hint) {
|
|
aHint = hint;
|
|
}
|
|
}
|
|
if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK;
|
|
if (aHint < NS_STYLE_HINT_MAX) {
|
|
hint = GETSCDATA(Outline).CalcDifference(other->GETSCDATA(Outline));
|
|
if (aHint < hint) {
|
|
aHint = hint;
|
|
}
|
|
}
|
|
if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK;
|
|
if (aHint < NS_STYLE_HINT_MAX) {
|
|
hint = GETSCDATA(List).CalcDifference(other->GETSCDATA(List));
|
|
if (aHint < hint) {
|
|
aHint = hint;
|
|
}
|
|
}
|
|
if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK;
|
|
if (aHint < NS_STYLE_HINT_MAX) {
|
|
hint = GETSCDATA(Position).CalcDifference(other->GETSCDATA(Position));
|
|
if (aHint < hint) {
|
|
aHint = hint;
|
|
}
|
|
}
|
|
if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK;
|
|
if (aHint < NS_STYLE_HINT_MAX) {
|
|
hint = GETSCDATA(Text).CalcDifference(other->GETSCDATA(Text));
|
|
if (aHint < hint) {
|
|
aHint = hint;
|
|
}
|
|
}
|
|
if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK;
|
|
if (aHint < NS_STYLE_HINT_MAX) {
|
|
hint = GETSCDATA(Display).CalcDifference(other->GETSCDATA(Display));
|
|
if (aHint < hint) {
|
|
aHint = hint;
|
|
}
|
|
}
|
|
if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK;
|
|
if (aHint < NS_STYLE_HINT_MAX) {
|
|
hint = GETSCDATA(Table).CalcDifference(other->GETSCDATA(Table));
|
|
if (aHint < hint) {
|
|
aHint = hint;
|
|
}
|
|
}
|
|
if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK;
|
|
if (aHint < NS_STYLE_HINT_MAX) {
|
|
hint = GETSCDATA(Content).CalcDifference(other->GETSCDATA(Content));
|
|
if (aHint < hint) {
|
|
aHint = hint;
|
|
}
|
|
}
|
|
if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK;
|
|
if (aHint < NS_STYLE_HINT_MAX) {
|
|
hint = GETSCDATA(UserInterface).CalcDifference(other->GETSCDATA(UserInterface));
|
|
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;
|
|
}
|
|
}
|
|
#ifdef INCLUDE_XUL
|
|
if (aStopAtFirstDifference && aHint > NS_STYLE_HINT_NONE) return NS_OK;
|
|
if (aHint < NS_STYLE_HINT_MAX) {
|
|
hint = GETSCDATA(XUL).CalcDifference(other->GETSCDATA(XUL));
|
|
if (aHint < hint) {
|
|
aHint = hint;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
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) {
|
|
NS_ASSERTION(mStyleSet, "Expected to have a style set ref...");
|
|
nsIStyleContext *matchingSC = nsnull;
|
|
|
|
// save the old crc before replacing it
|
|
PRUint32 oldCRC = mStyleData->GetCRC32();
|
|
|
|
// set the CRC based on the new data, and retrieve the new value
|
|
mStyleData->SetCRC32();
|
|
PRUint32 newCRC = mStyleData->GetCRC32();
|
|
|
|
// if the crc was previously set AND it has changed, notify the styleset
|
|
if((oldCRC != STYLEDATA_NO_CRC)&&
|
|
(oldCRC != newCRC)) {
|
|
result = mStyleSet->UpdateStyleContextKey(oldCRC, newCRC);
|
|
#ifdef NOISY_DEBUG
|
|
printf("CRC changed on context: updating from %ld to %ld\n", oldCRC, newCRC);
|
|
#endif
|
|
if(NS_FAILED(result)) {
|
|
return result;
|
|
}
|
|
}
|
|
// 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
|
|
|
|
void StyleContextImpl::List(FILE* out, PRInt32 aIndent)
|
|
{
|
|
// Indent
|
|
PRInt32 ix;
|
|
for (ix = aIndent; --ix >= 0; ) fputs(" ", out);
|
|
fprintf(out, "%p(%d) ", (void*)this, mRefCnt);
|
|
if (nsnull != mPseudoTag) {
|
|
nsAutoString buffer;
|
|
mPseudoTag->ToString(buffer);
|
|
fputs(buffer, out);
|
|
fputs(" ", out);
|
|
}
|
|
PRInt32 count = GetStyleRuleCount();
|
|
if (0 < count) {
|
|
fputs("{\n", out);
|
|
|
|
for (ix = 0; ix < count; ix++) {
|
|
nsIStyleRule* rule = (nsIStyleRule*)mRules->ElementAt(ix);
|
|
rule->List(out, aIndent + 1);
|
|
NS_RELEASE(rule);
|
|
}
|
|
|
|
for (ix = aIndent; --ix >= 0; ) fputs(" ", out);
|
|
fputs("}\n", out);
|
|
}
|
|
else {
|
|
fputs("{}\n", out);
|
|
}
|
|
|
|
if (nsnull != mChild) {
|
|
StyleContextImpl* child = mChild;
|
|
do {
|
|
child->List(out, aIndent + 1);
|
|
child = child->mNextSibling;
|
|
} while (mChild != child);
|
|
}
|
|
if (nsnull != mEmptyChild) {
|
|
StyleContextImpl* child = mEmptyChild;
|
|
do {
|
|
child->List(out, aIndent + 1);
|
|
child = child->mNextSibling;
|
|
} while (mEmptyChild != child);
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
* 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( " - 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( " - StyleMarginImpl: %ld\n", (long)sizeof(GETSCDATA(Margin)));
|
|
totalSize += (long)sizeof(GETSCDATA(Margin));
|
|
printf( " - StylePaddingImpl: %ld\n", (long)sizeof(GETSCDATA(Padding)));
|
|
totalSize += (long)sizeof(GETSCDATA(Padding));
|
|
printf( " - StyleBorderImpl: %ld\n", (long)sizeof(GETSCDATA(Border)));
|
|
totalSize += (long)sizeof(GETSCDATA(Border));
|
|
printf( " - StyleOutlineImpl: %ld\n", (long)sizeof(GETSCDATA(Outline)));
|
|
totalSize += (long)sizeof(GETSCDATA(Outline));
|
|
#ifdef INCLUDE_XUL
|
|
printf( " - StyleXULImpl: %ld\n", (long)sizeof(GETSCDATA(XUL)));
|
|
totalSize += (long)sizeof(GETSCDATA(XUL));
|
|
#endif
|
|
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 (ie. margin, padding, border, outline)
|
|
IndentBy(out,aIndent);
|
|
fprintf(out, "<spacing data=\"");
|
|
|
|
GETSCDATA(Margin).mMargin.ToString(str);
|
|
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
|
|
GETSCDATA(Padding).mPadding.ToString(str);
|
|
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
|
|
GETSCDATA(Border).mBorder.ToString(str);
|
|
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
|
|
GETSCDATA(Border).mBorderRadius.ToString(str);
|
|
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
|
|
GETSCDATA(Outline).mOutlineRadius.ToString(str);
|
|
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
|
|
GETSCDATA(Outline).mOutlineWidth.ToString(str);
|
|
fprintf(out, "%s", NS_ConvertUCS2toUTF8(str).get());
|
|
fprintf(out, "%d", (int)GETSCDATA(Border).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
|
|
|
|
NS_LAYOUT nsresult
|
|
NS_NewStyleContext(nsIStyleContext** aInstancePtrResult,
|
|
nsIStyleContext* aParentContext,
|
|
nsIAtom* aPseudoTag,
|
|
nsISupportsArray* aRules,
|
|
nsIPresContext* aPresContext)
|
|
{
|
|
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
|
|
if (nsnull == aInstancePtrResult) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
StyleContextImpl* context = new StyleContextImpl(aParentContext, aPseudoTag,
|
|
aRules, aPresContext);
|
|
if (nsnull == context) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
nsresult result = context->QueryInterface(NS_GET_IID(nsIStyleContext), (void **) aInstancePtrResult);
|
|
context->RemapStyle(aPresContext); // remap after initial ref-count is set
|
|
|
|
#ifdef SHARE_STYLECONTEXTS
|
|
context->UpdateStyleSetCache(); // add it to the style set cache now that the CRC is set
|
|
#endif
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------
|
|
|
|
#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 = aCrc;
|
|
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_LIST_ITEM :
|
|
// do not change list items to blocks - retain the bullet/numbering
|
|
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;
|
|
}
|
|
}
|