Ensure that GetStyleData never returns null, even in out-of-memory, by storing a backup set of style structs to return in case of failure. b=154751 r+sr=bzbarsky

This commit is contained in:
dbaron%dbaron.org 2003-03-13 15:29:36 +00:00
parent d4fface64d
commit 3069e2548c
19 changed files with 539 additions and 266 deletions

View File

@ -416,9 +416,9 @@ nsRuleNode::Destroy()
mPresContext->FreeToShell(sizeof(nsRuleNode), this);
}
void nsRuleNode::CreateRootNode(nsIPresContext* aPresContext, nsRuleNode** aResult)
nsRuleNode* nsRuleNode::CreateRootNode(nsIPresContext* aPresContext)
{
*aResult = new (aPresContext) nsRuleNode(aPresContext);
return new (aPresContext) nsRuleNode(aPresContext, nsnull, nsnull);
}
nsILanguageAtomService* nsRuleNode::gLangService = nsnull;
@ -555,6 +555,8 @@ nsRuleNode::PathContainsRule(nsIStyleRule* aRule, PRBool* aMatched)
nsresult
nsRuleNode::ClearCachedData(nsIStyleRule* aRule)
{
NS_ASSERTION(aRule, "you should be using ClearCachedDataInSubtree");
nsRuleNode* ruleDest = this;
while (ruleDest) {
if (ruleDest->mRule == aRule)
@ -563,6 +565,8 @@ nsRuleNode::ClearCachedData(nsIStyleRule* aRule)
}
if (ruleDest) {
NS_ASSERTION(ruleDest->mParent, "node must not be root");
// The rule was contained along our branch. We need to blow away
// all cached data along this path. Note that, because of the definition
// of inline style, all nodes along this path must have exactly one child. This
@ -603,8 +607,10 @@ nsRuleNode::ClearCachedDataInSubtree(nsIStyleRule* aRule)
// We have a match. Blow away all data stored at this node.
if (mStyleData.mResetData || mStyleData.mInheritedData)
mStyleData.Destroy(0, mPresContext);
mNoneBits &= ~NS_STYLE_INHERIT_MASK;
mDependentBits &= ~NS_STYLE_INHERIT_MASK;
aRule = nsnull; // Cause everything to be blown away in the descendants.
}
@ -980,7 +986,7 @@ static const PropertyCheckData SVGCheckProperties[] = {
static const StructCheckData gCheckProperties[] = {
#define STYLE_STRUCT(name, checkdata_cb) \
#define STYLE_STRUCT(name, checkdata_cb, ctor_args) \
{name##CheckProperties, \
sizeof(name##CheckProperties)/sizeof(PropertyCheckData), \
checkdata_cb},
@ -1608,16 +1614,6 @@ nsRuleNode::WalkRuleTree(const nsStyleStructID aSID,
return res;
}
static nscoord
ZoomFont(nsIPresContext* aPresContext, nscoord aInSize)
{
nsCOMPtr<nsIDeviceContext> dc;
aPresContext->GetDeviceContext(getter_AddRefs(dc));
float textZoom;
dc->GetTextZoom(textZoom);
return nscoord(aInSize * textZoom);
}
static PRBool
IsChrome(nsIPresContext* aPresContext)
{
@ -1643,10 +1639,7 @@ nsRuleNode::SetDefaultOnRoot(const nsStyleStructID aSID, nsStyleContext* aContex
switch (aSID) {
case eStyleStruct_Font:
{
const nsFont* defaultFont;
mPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID, &defaultFont);
nsStyleFont* fontData = new (mPresContext) nsStyleFont(*defaultFont);
fontData->mSize = ZoomFont(mPresContext, fontData->mFont.size);
nsStyleFont* fontData = new (mPresContext) nsStyleFont(mPresContext);
nscoord minimumFontSize = 0;
mPresContext->GetCachedIntPref(kPresContext_MinimumFontSize, minimumFontSize);
@ -1792,7 +1785,7 @@ nsRuleNode::SetDefaultOnRoot(const nsStyleStructID aSID, nsStyleContext* aContex
nsRuleNode::ComputeStyleDataFn
nsRuleNode::gComputeStyleDataFn[] = {
#define STYLE_STRUCT(name, checkdata_cb) \
#define STYLE_STRUCT(name, checkdata_cb, ctor_args) \
&nsRuleNode::Compute##name##Data,
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
@ -1805,7 +1798,7 @@ SetFont(nsIPresContext* aPresContext, nsStyleContext* aContext,
nscoord aMinFontSize, PRBool aUseDocumentFonts, PRBool aChromeOverride,
PRBool aIsGeneric, const nsRuleDataFont& aFontData,
const nsFont& aDefaultFont, const nsStyleFont* aParentFont,
nsStyleFont* aFont, PRBool aZoom, PRBool& aInherited)
nsStyleFont* aFont, PRBool& aInherited)
{
const nsFont* defaultVariableFont;
const nsFont* defaultFixedFont;
@ -1863,7 +1856,9 @@ SetFont(nsIPresContext* aPresContext, nsStyleContext* aContext,
if (NS_FAILED(dc->GetSystemFont(sysID, &aFont->mFont))) {
aFont->mFont.name = defaultVariableFont->name;
}
aFont->mSize = aFont->mFont.size; // this becomes our cascading size
// this becomes our cascading size
aFont->mSize = aFont->mFont.size
= nsStyleFont::ZoomText(aPresContext, aFont->mFont.size);
}
aFont->mFont.familyNameQuirks = PR_FALSE;
@ -1964,7 +1959,7 @@ SetFont(nsIPresContext* aPresContext, nsStyleContext* aContext,
}
// font-size: enum, length, percent, inherit
PRBool zoom = aZoom;
PRBool zoom = PR_FALSE;
if (eCSSUnit_Enumerated == aFontData.mSize.GetUnit()) {
PRInt32 value = aFontData.mSize.GetIntValue();
PRInt32 scaler;
@ -1987,12 +1982,8 @@ SetFont(nsIPresContext* aPresContext, nsStyleContext* aContext,
// Un-zoom so we use the tables correctly. We'll then rezoom due
// to the |zoom = PR_TRUE| above.
nsCOMPtr<nsIDeviceContext> dc;
aPresContext->GetDeviceContext(getter_AddRefs(dc));
float textZoom;
dc->GetTextZoom(textZoom);
nscoord parentSize = nscoord(aParentFont->mSize / textZoom);
nscoord parentSize =
nsStyleFont::UnZoomText(aPresContext, aParentFont->mSize);
if (NS_STYLE_FONT_SIZE_LARGER == value) {
PRInt32 index = nsStyleUtil::FindNextLargerFontSize(parentSize, (PRInt32)aDefaultFont.size,
@ -2058,7 +2049,7 @@ SetFont(nsIPresContext* aPresContext, nsStyleContext* aContext,
// We want to zoom the cascaded size so that em-based measurements,
// line-heights, etc., work.
if (zoom)
aFont->mSize = ZoomFont(aPresContext, aFont->mSize);
aFont->mSize = nsStyleFont::ZoomText(aPresContext, aFont->mSize);
// enforce the user' specified minimum font-size on the value that we expose
if (aChromeOverride) {
@ -2116,8 +2107,9 @@ SetGenericFont(nsIPresContext* aPresContext, nsStyleContext* aContext,
const nsFont* defaultFont;
aPresContext->GetDefaultFont(aGenericFontID, &defaultFont);
nsStyleFont parentFont(*defaultFont);
parentFont.mSize = parentFont.mFont.size
= nsStyleFont::ZoomText(aPresContext, parentFont.mSize);
PRInt32 i = contextPath.Count() - 1;
PRBool zoom = PR_TRUE;
if (higherContext) {
nsStyleContext* context = (nsStyleContext*)contextPath[i];
nsStyleFont* tmpFont = (nsStyleFont*)context->GetStyleData(eStyleStruct_Font);
@ -2125,7 +2117,6 @@ SetGenericFont(nsIPresContext* aPresContext, nsStyleContext* aContext,
parentFont.mFont = tmpFont->mFont;
parentFont.mSize = tmpFont->mSize;
--i;
zoom = PR_FALSE;
}
aFont->mFlags = parentFont.mFlags;
aFont->mFont = parentFont.mFont;
@ -2163,7 +2154,7 @@ SetGenericFont(nsIPresContext* aPresContext, nsStyleContext* aContext,
SetFont(aPresContext, context, aMinFontSize,
aUseDocumentFonts, aChromeOverride, PR_TRUE,
fontData, *defaultFont, &parentFont, aFont, zoom, dummy);
fontData, *defaultFont, &parentFont, aFont, dummy);
// XXX Not sure if we need to do this here
// If we have a post-resolve callback, handle that now.
@ -2173,7 +2164,6 @@ SetGenericFont(nsIPresContext* aPresContext, nsStyleContext* aContext,
parentFont.mFlags = aFont->mFlags;
parentFont.mFont = aFont->mFont;
parentFont.mSize = aFont->mSize;
zoom = PR_FALSE;
}
// Finish off by applying our own rules. In this case, aFontData
@ -2181,7 +2171,7 @@ SetGenericFont(nsIPresContext* aPresContext, nsStyleContext* aContext,
// can just compute the delta from the parent.
SetFont(aPresContext, aContext, aMinFontSize,
aUseDocumentFonts, aChromeOverride, PR_TRUE,
aFontData, *defaultFont, &parentFont, aFont, zoom, dummy);
aFontData, *defaultFont, &parentFont, aFont, dummy);
}
const nsStyleStruct*
@ -2222,12 +2212,8 @@ nsRuleNode::ComputeFontData(nsStyleStruct* aStartStruct,
}
}
PRBool zoom = PR_FALSE;
const nsFont* defaultFont;
if (!font) {
mPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID, &defaultFont);
font = new (mPresContext) nsStyleFont(*defaultFont);
zoom = PR_TRUE;
font = new (mPresContext) nsStyleFont(mPresContext);
}
if (!parentFont)
parentFont = font;
@ -2268,6 +2254,8 @@ nsRuleNode::ComputeFontData(nsStyleStruct* aStartStruct,
// determine if we have to override the minimum font-size constraint.
if (!useDocumentFonts || minimumFontSize > 0) {
chromeOverride = IsChrome(mPresContext);
// XXXldb Just fix up |useDocumentFonts| here and drop the
// |chromeOverride| variable from here on!
}
// If we don't have to use document fonts, then we are only entitled
@ -2282,10 +2270,11 @@ nsRuleNode::ComputeFontData(nsStyleStruct* aStartStruct,
// continue the normal processing
// our default font is the most recent generic font
generic = parentFont->mFlags & NS_STYLE_FONT_FACE_MASK;
const nsFont* defaultFont;
mPresContext->GetDefaultFont(generic, &defaultFont);
SetFont(mPresContext, aContext, minimumFontSize,
useDocumentFonts, chromeOverride, PR_FALSE,
fontData, *defaultFont, parentFont, font, zoom, inherited);
fontData, *defaultFont, parentFont, font, inherited);
}
else {
// re-calculate the font as a generic font
@ -2368,8 +2357,8 @@ nsRuleNode::ComputeTextData(nsStyleStruct* aStartStruct,
aContext, mPresContext, inherited);
if (textData.mLineHeight.IsFixedLengthUnit() ||
textData.mLineHeight.GetUnit() == eCSSUnit_Pixel)
text->mLineHeight.SetCoordValue(
ZoomFont(mPresContext, text->mLineHeight.GetCoordValue()));
text->mLineHeight.SetCoordValue(nsStyleFont::ZoomText(mPresContext,
text->mLineHeight.GetCoordValue()));
}
@ -4637,24 +4626,31 @@ nsRuleNode::ComputeSVGData(nsStyleStruct* aStartStruct,
inline const nsStyleStruct*
nsRuleNode::GetParentData(const nsStyleStructID aSID)
{
nsRuleNode* ruleNode = mParent;
nsStyleStruct* currStruct = nsnull;
while (ruleNode) {
currStruct = ruleNode->mStyleData.GetStyleData(aSID);
if (currStruct)
break; // We found a rule with fully specified data. We don't need to go up
// the tree any further, since the remainder of this branch has already
// been computed.
ruleNode = ruleNode->mParent; // Climb up to the next rule in the tree (a less specific rule).
}
// Walk up the rule tree from this rule node (towards less specific
// rules).
for (nsRuleNode* ruleNode = mParent; ruleNode; ruleNode = ruleNode->mParent)
{
const nsStyleStruct *currStruct = ruleNode->mStyleData.GetStyleData(aSID);
if (currStruct) {
// We found a rule with fully specified data. We don't need to go
// up the tree any further, since the remainder of this branch has
// already been computed.
return currStruct;
}
NS_ASSERTION(ruleNode->mDependentBits &
nsCachedStyleData::GetBitForSID(aSID),
"dependent bits improperly set");
}
return currStruct; // Just return whatever we found.
NS_NOTREACHED("dependent bits set on root or improperly set");
return nsnull;
}
nsRuleNode::GetStyleDataFn
nsRuleNode::gGetStyleDataFn[] = {
#define STYLE_STRUCT(name, checkdata_cb) &nsRuleNode::Get##name##Data,
#define STYLE_STRUCT(name, checkdata_cb, ctor_args) \
&nsRuleNode::Get##name##Data,
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
@ -4666,21 +4662,42 @@ nsRuleNode::GetStyleData(nsStyleStructID aSID,
nsStyleContext* aContext,
PRBool aComputeData)
{
const nsStyleStruct* cachedData = mStyleData.GetStyleData(aSID);
if (cachedData)
return cachedData; // We have a fully specified struct. Just return it.
const nsStyleStruct* data = mStyleData.GetStyleData(aSID);
if (data)
return data; // We have a fully specified struct. Just return it.
if (mDependentBits & nsCachedStyleData::GetBitForSID(aSID))
return GetParentData(aSID); // We depend on an ancestor for this
// struct since the cached struct it has
// is also appropriate for this rule
// node. Just go up the rule tree and
// return the first cached struct we
// find.
if (mDependentBits & nsCachedStyleData::GetBitForSID(aSID)) {
// We depend on an ancestor for this struct since the cached struct
// it has is also appropriate for this rule node. Just go up the
// rule tree and return the first cached struct we find.
data = GetParentData(aSID);
if (data)
return data;
NS_NOTREACHED("dependent bits set but no cached struct present");
}
// Nothing is cached. We'll have to delve further and examine our rules.
GetStyleDataFn fn = gGetStyleDataFn[aSID];
return fn ? (this->*fn)(aContext, aComputeData) : nsnull;
if (!fn) {
NS_NOTREACHED("unknown style struct requested");
return nsnull;
}
data = (this->*fn)(aContext, aComputeData);
if (data || !aComputeData)
return data;
NS_NOTREACHED("could not create style struct");
// To ensure that |GetStyleData| never returns null (even when we're
// out of memory), we'll get the style set and get a copy of the
// default values for the given style struct from the set. Note that
// this works fine even if |this| is a rule node that has been
// destroyed (leftover from a previous rule tree) but is somehow still
// used.
nsCOMPtr<nsIPresShell> shell;
mPresContext->GetShell(getter_AddRefs(shell));
nsCOMPtr<nsIStyleSet> set;
shell->GetStyleSet(getter_AddRefs(set));
return set->GetDefaultStyleData()->GetStyleData(aSID);
}
void

View File

@ -189,6 +189,10 @@ public:
virtual nsresult BeginRuleTreeReconstruct();
virtual nsresult EndRuleTreeReconstruct();
// For getting the cached default data in case we hit out-of-memory.
// To be used only by nsRuleNode.
virtual nsCachedStyleData* GetDefaultStyleData();
virtual nsresult GetRuleTree(nsRuleNode** aResult);
virtual nsresult ClearCachedDataInRuleTree(nsIStyleRule* aRule);
@ -319,6 +323,9 @@ protected:
void EnsureRuleWalker(nsIPresContext* aPresContext);
// Returns false on out-of-memory.
PRBool BuildDefaultStyleData(nsIPresContext* aPresContext);
void ClearRuleProcessors(void);
void ClearAgentRuleProcessors(void);
void ClearUserRuleProcessors(void);
@ -365,6 +372,11 @@ protected:
nsCOMPtr<nsIStyleRuleSupplier> mStyleRuleSupplier;
// To be used only in case of emergency, such as being out of memory
// or operating on a deleted rule node. The latter should never
// happen, of course.
nsCachedStyleData mDefaultStyleData;
nsRuleNode* mRuleTree; // This is the root of our rule tree. It is a lexicographic tree of
// matched rules that style contexts use to look up properties.
nsRuleNode* mOldRuleTree; // Used during rule tree reconstruction.
@ -1143,25 +1155,55 @@ StyleSetImpl::WalkRuleProcessors(nsISupportsArrayEnumFunc aFunc,
mOverrideRuleProcessors->EnumerateForwards(aFunc, aData);
}
#ifdef NS_DEBUG
#define NS_ASSERT_REFCOUNT(ptr,cnt,msg) { \
nsrefcnt count = ptr->AddRef(); \
ptr->Release(); \
NS_ASSERTION(--count == cnt, msg); \
}
#else
#define NS_ASSERT_REFCOUNT(ptr,cnt,msg) {}
#endif
void StyleSetImpl::EnsureRuleWalker(nsIPresContext* aPresContext)
{
{
if (mRuleWalker)
return;
nsRuleNode::CreateRootNode(aPresContext, &mRuleTree);
if (!mDefaultStyleData.mResetData && !BuildDefaultStyleData(aPresContext)) {
mDefaultStyleData.Destroy(0, aPresContext);
return;
}
mRuleTree = nsRuleNode::CreateRootNode(aPresContext);
if (!mRuleTree)
return;
mRuleWalker = new nsRuleWalker(mRuleTree);
}
PRBool StyleSetImpl::BuildDefaultStyleData(nsIPresContext* aPresContext)
{
NS_ASSERTION(!mDefaultStyleData.mResetData &&
!mDefaultStyleData.mInheritedData,
"leaking default style data");
mDefaultStyleData.mResetData = new (aPresContext) nsResetStyleData;
if (!mDefaultStyleData.mResetData)
return PR_FALSE;
mDefaultStyleData.mInheritedData = new (aPresContext) nsInheritedStyleData;
if (!mDefaultStyleData.mInheritedData)
return PR_FALSE;
#define SSARG_PRESCONTEXT aPresContext
#define CREATE_DATA(name, type, args) \
if (!(mDefaultStyleData.m##type##Data->m##name##Data = \
new (aPresContext) nsStyle##name args)) \
return PR_FALSE;
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args) \
CREATE_DATA(name, Inherited, ctor_args)
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args) \
CREATE_DATA(name, Reset, ctor_args)
#include "nsStyleStructList.h"
#undef STYLE_STRUCT_INHERITED
#undef STYLE_STRUCT_RESET
#undef SSARG_PRESCONTEXT
return PR_TRUE;
}
already_AddRefed<nsStyleContext>
StyleSetImpl::ResolveStyleFor(nsIPresContext* aPresContext,
nsIContent* aContent,
@ -1184,6 +1226,7 @@ StyleSetImpl::ResolveStyleFor(nsIPresContext* aPresContext,
mDocRuleProcessors ||
mOverrideRuleProcessors) {
EnsureRuleWalker(aPresContext);
NS_ENSURE_TRUE(mRuleWalker, nsnull);
nsCOMPtr<nsIAtom> medium;
aPresContext->GetMedium(getter_AddRefs(medium));
RulesMatchingData data(aPresContext, medium, aContent, mRuleWalker);
@ -1218,6 +1261,7 @@ StyleSetImpl::ResolveStyleForNonElement(nsIPresContext* aPresContext,
mDocRuleProcessors ||
mOverrideRuleProcessors) {
EnsureRuleWalker(aPresContext);
NS_ENSURE_TRUE(mRuleWalker, nsnull);
result = GetContext(aPresContext, aParentContext,
nsCSSAnonBoxes::mozNonElement).get();
NS_ASSERTION(mRuleWalker->AtRoot(), "rule walker must be at root");
@ -1282,6 +1326,7 @@ StyleSetImpl::ResolvePseudoStyleFor(nsIPresContext* aPresContext,
nsCOMPtr<nsIAtom> medium;
aPresContext->GetMedium(getter_AddRefs(medium));
EnsureRuleWalker(aPresContext);
NS_ENSURE_TRUE(mRuleWalker, nsnull);
PseudoRulesMatchingData data(aPresContext, medium, aParentContent,
aPseudoTag, aComparator, mRuleWalker);
FileRules(EnumPseudoRulesMatching, &data);
@ -1324,6 +1369,7 @@ StyleSetImpl::ProbePseudoStyleFor(nsIPresContext* aPresContext,
nsCOMPtr<nsIAtom> medium;
aPresContext->GetMedium(getter_AddRefs(medium));
EnsureRuleWalker(aPresContext);
NS_ENSURE_TRUE(mRuleWalker, nsnull);
PseudoRulesMatchingData data(aPresContext, medium, aParentContent,
aPseudoTag, nsnull, mRuleWalker);
FileRules(EnumPseudoRulesMatching, &data);
@ -1378,11 +1424,15 @@ NS_IMETHODIMP
StyleSetImpl::Shutdown(nsIPresContext* aPresContext)
{
delete mRuleWalker;
mRuleWalker = nsnull;
if (mRuleTree)
{
mRuleTree->Destroy();
mRuleTree = nsnull;
}
mDefaultStyleData.Destroy(0, aPresContext);
return NS_OK;
}
@ -1450,6 +1500,12 @@ StyleSetImpl::EndRuleTreeReconstruct()
return NS_OK;
}
nsCachedStyleData*
StyleSetImpl::GetDefaultStyleData()
{
return &mDefaultStyleData;
}
nsresult
StyleSetImpl::ClearCachedDataInRuleTree(nsIStyleRule* aInlineStyleRule)
{
@ -1507,6 +1563,7 @@ StyleSetImpl::ReParentStyleContext(nsIPresContext* aPresContext,
nsRuleNode* ruleNode;
aStyleContext->GetRuleNode(&ruleNode);
EnsureRuleWalker(aPresContext);
NS_ENSURE_TRUE(mRuleWalker, nsnull);
mRuleWalker->SetCurrentNode(ruleNode);
already_AddRefed<nsStyleContext> result =
@ -1845,14 +1902,9 @@ void StyleSetImpl::ListContexts(nsIFrame* aRootFrame, FILE* out, PRInt32 aIndent
nsresult
NS_NewStyleSet(nsIStyleSet** aInstancePtrResult)
{
if (!aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
StyleSetImpl *it = new StyleSetImpl();
if (!it) {
StyleSetImpl *it = new StyleSetImpl();
if (!it)
return NS_ERROR_OUT_OF_MEMORY;
}
return CallQueryInterface(it, aInstancePtrResult);
}

View File

@ -66,11 +66,11 @@
nsCachedStyleData::StyleStructInfo
nsCachedStyleData::gInfo[] = {
#define STYLE_STRUCT_INHERITED(name, checkdata_cb) \
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args) \
{ offsetof(nsCachedStyleData, mInheritedData), \
offsetof(nsInheritedStyleData, m##name##Data), \
PR_FALSE },
#define STYLE_STRUCT_RESET(name, checkdata_cb) \
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args) \
{ offsetof(nsCachedStyleData, mResetData), \
offsetof(nsResetStyleData, m##name##Data), \
PR_TRUE },

View File

@ -57,9 +57,9 @@ typedef void (*nsPostResolveFunc)(nsStyleStruct* aStyleStruct, nsRuleData* aData
struct nsInheritedStyleData
{
#define STYLE_STRUCT_INHERITED(name, checkdata_cb) \
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args) \
nsStyle##name * m##name##Data;
#define STYLE_STRUCT_RESET(name, checkdata_cb)
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args)
#include "nsStyleStructList.h"
@ -73,10 +73,10 @@ struct nsInheritedStyleData
};
void ClearInheritedData(PRUint32 aBits) {
#define STYLE_STRUCT_INHERITED(name, checkdata_cb) \
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args) \
if (m##name##Data && (aBits & NS_STYLE_INHERIT_BIT(name))) \
m##name##Data = nsnull;
#define STYLE_STRUCT_RESET(name, checkdata_cb)
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args)
#include "nsStyleStructList.h"
@ -85,10 +85,10 @@ struct nsInheritedStyleData
};
void Destroy(PRUint32 aBits, nsIPresContext* aContext) {
#define STYLE_STRUCT_INHERITED(name, checkdata_cb) \
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args) \
if (m##name##Data && !(aBits & NS_STYLE_INHERIT_BIT(name))) \
m##name##Data->Destroy(aContext);
#define STYLE_STRUCT_RESET(name, checkdata_cb)
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args)
#include "nsStyleStructList.h"
@ -99,9 +99,9 @@ struct nsInheritedStyleData
};
nsInheritedStyleData() {
#define STYLE_STRUCT_INHERITED(name, checkdata_cb) \
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args) \
m##name##Data = nsnull;
#define STYLE_STRUCT_RESET(name, checkdata_cb)
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args)
#include "nsStyleStructList.h"
@ -115,9 +115,9 @@ struct nsResetStyleData
{
nsResetStyleData()
{
#define STYLE_STRUCT_RESET(name, checkdata_cb) \
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args) \
m##name##Data = nsnull;
#define STYLE_STRUCT_INHERITED(name, checkdata_cb)
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args)
#include "nsStyleStructList.h"
@ -132,10 +132,10 @@ struct nsResetStyleData
}
void ClearInheritedData(PRUint32 aBits) {
#define STYLE_STRUCT_RESET(name, checkdata_cb) \
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args) \
if (m##name##Data && (aBits & NS_STYLE_INHERIT_BIT(name))) \
m##name##Data = nsnull;
#define STYLE_STRUCT_INHERITED(name, checkdata_cb)
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args)
#include "nsStyleStructList.h"
@ -144,10 +144,10 @@ struct nsResetStyleData
};
void Destroy(PRUint32 aBits, nsIPresContext* aContext) {
#define STYLE_STRUCT_RESET(name, checkdata_cb) \
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args) \
if (m##name##Data && !(aBits & NS_STYLE_INHERIT_BIT(name))) \
m##name##Data->Destroy(aContext);
#define STYLE_STRUCT_INHERITED(name, checkdata_cb)
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args)
#include "nsStyleStructList.h"
@ -157,9 +157,9 @@ struct nsResetStyleData
aContext->FreeToShell(sizeof(nsResetStyleData), this);
};
#define STYLE_STRUCT_RESET(name, checkdata_cb) \
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args) \
nsStyle##name * m##name##Data;
#define STYLE_STRUCT_INHERITED(name, checkdata_cb)
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args)
#include "nsStyleStructList.h"
@ -542,10 +542,11 @@ protected:
static GetStyleDataFn gGetStyleDataFn[];
public:
nsRuleNode(nsIPresContext* aPresContext, nsIStyleRule* aRule=nsnull, nsRuleNode* aParent=nsnull);
nsRuleNode(nsIPresContext* aPresContext, nsIStyleRule* aRule,
nsRuleNode* aParent);
virtual ~nsRuleNode();
static void CreateRootNode(nsIPresContext* aPresContext, nsRuleNode** aResult);
static nsRuleNode* CreateRootNode(nsIPresContext* aPresContext);
nsresult GetBits(PRInt32 aType, PRUint32* aResult);
nsresult Transition(nsIStyleRule* aRule, nsRuleNode** aResult);

View File

@ -98,7 +98,27 @@ public:
*/
void Mark();
/*
* Get the style data for a style struct. This is the most important
* member function of nsIStyleContext. It fills in a const pointer
* to a style data struct that is appropriate for the style context's
* frame. This struct may be shared with other contexts (either in
* the rule tree or the style context tree), so it should not be
* modified.
*
* This function will NOT return null (even when out of memory) when
* given a valid style struct ID, so the result does not need to be
* null-checked.
*
* The typesafe global helper function |GetStyleData| (below) is
* preferred to the use of this function (and is a simple typesafe
* wrapper for this function).
*
* See also |nsIFrame::GetStyleData| and the other global
* |GetStyleData| in nsIFrame.h.
*/
const nsStyleStruct* GetStyleData(nsStyleStructID aSID);
const nsStyleStruct* PeekStyleData(nsStyleStructID aSID);
nsStyleStruct* GetUniqueStyleData(nsIPresContext* aPresContext, const nsStyleStructID& aSID);

View File

@ -64,7 +64,7 @@ enum nsStyleStructID {
* increase by 1.
*/
#define STYLE_STRUCT(name, checkdata_cb) eStyleStruct_##name,
#define STYLE_STRUCT(name, checkdata_cb, ctor_args) eStyleStruct_##name,
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
@ -96,12 +96,18 @@ struct nsStyleStruct {
struct nsStyleFont : public nsStyleStruct {
nsStyleFont(void);
nsStyleFont(const nsFont& aFont);
nsStyleFont(const nsStyleFont& aStyleFont);
nsStyleFont(nsIPresContext *aPresContext);
~nsStyleFont(void) {};
NS_DEFINE_STATIC_STYLESTRUCTID_ACCESSOR(eStyleStruct_Font)
nsChangeHint CalcDifference(const nsStyleFont& aOther) const;
static nsChangeHint CalcFontDifference(const nsFont& aFont1, const nsFont& aFont2);
static nscoord ZoomText(nsIPresContext* aPresContext, nscoord aSize);
static nscoord UnZoomText(nsIPresContext* aPresContext, nscoord aSize);
void* operator new(size_t sz, nsIPresContext* aContext) CPP_THROW_NEW;
void Destroy(nsIPresContext* aContext);
@ -112,10 +118,6 @@ struct nsStyleFont : public nsStyleStruct {
// which is our "actual size" and is enforced to be >= the user's
// preferred min-size. mFont.size should be used for display purposes
// while mSize is the value to return in getComputedStyle() for example.
nsStyleFont(const nsFont& aFont);
nsStyleFont(const nsStyleFont& aStyleFont);
nsStyleFont(nsIPresContext* aPresContext);
};
struct nsStyleColor : public nsStyleStruct {

View File

@ -44,40 +44,41 @@
*/
#ifndef STYLE_STRUCT_INHERITED
#define STYLE_STRUCT_INHERITED(name, checkdata_cb) \
STYLE_STRUCT(name, checkdata_cb)
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args) \
STYLE_STRUCT(name, checkdata_cb, ctor_args)
#define UNDEF_STYLE_STRUCT_INHERITED
#endif
#ifndef STYLE_STRUCT_RESET
#define STYLE_STRUCT_RESET(name, checkdata_cb) STYLE_STRUCT(name, checkdata_cb)
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args) \
STYLE_STRUCT(name, checkdata_cb, ctor_args)
#define UNDEF_STYLE_STRUCT_RESET
#endif
STYLE_STRUCT_INHERITED(Font, CheckFontCallback)
STYLE_STRUCT_INHERITED(Color, nsnull)
STYLE_STRUCT_RESET(Background, nsnull)
STYLE_STRUCT_INHERITED(List, nsnull)
STYLE_STRUCT_RESET(Position, nsnull)
STYLE_STRUCT_INHERITED(Text, nsnull)
STYLE_STRUCT_RESET(TextReset, nsnull)
STYLE_STRUCT_RESET(Display, nsnull)
STYLE_STRUCT_INHERITED(Visibility, nsnull)
STYLE_STRUCT_RESET(Content, nsnull)
STYLE_STRUCT_INHERITED(Quotes, nsnull)
STYLE_STRUCT_INHERITED(UserInterface, nsnull)
STYLE_STRUCT_RESET(UIReset, nsnull)
STYLE_STRUCT_RESET(Table, nsnull)
STYLE_STRUCT_INHERITED(TableBorder, nsnull)
STYLE_STRUCT_RESET(Margin, nsnull)
STYLE_STRUCT_RESET(Padding, nsnull)
STYLE_STRUCT_RESET(Border, nsnull)
STYLE_STRUCT_RESET(Outline, nsnull)
STYLE_STRUCT_INHERITED(Font, CheckFontCallback, (SSARG_PRESCONTEXT))
STYLE_STRUCT_INHERITED(Color, nsnull, (SSARG_PRESCONTEXT))
STYLE_STRUCT_RESET(Background, nsnull, (SSARG_PRESCONTEXT))
STYLE_STRUCT_INHERITED(List, nsnull, ())
STYLE_STRUCT_RESET(Position, nsnull, ())
STYLE_STRUCT_INHERITED(Text, nsnull, ())
STYLE_STRUCT_RESET(TextReset, nsnull, ())
STYLE_STRUCT_RESET(Display, nsnull, ())
STYLE_STRUCT_INHERITED(Visibility, nsnull, (SSARG_PRESCONTEXT))
STYLE_STRUCT_RESET(Content, nsnull, ())
STYLE_STRUCT_INHERITED(Quotes, nsnull, ())
STYLE_STRUCT_INHERITED(UserInterface, nsnull, ())
STYLE_STRUCT_RESET(UIReset, nsnull, ())
STYLE_STRUCT_RESET(Table, nsnull, ())
STYLE_STRUCT_INHERITED(TableBorder, nsnull, (SSARG_PRESCONTEXT))
STYLE_STRUCT_RESET(Margin, nsnull, ())
STYLE_STRUCT_RESET(Padding, nsnull, ())
STYLE_STRUCT_RESET(Border, nsnull, ())
STYLE_STRUCT_RESET(Outline, nsnull, (SSARG_PRESCONTEXT))
#ifdef INCLUDE_XUL
STYLE_STRUCT_RESET(XUL, nsnull)
STYLE_STRUCT_RESET(XUL, nsnull, ())
#endif
#ifdef MOZ_SVG
STYLE_STRUCT_INHERITED(SVG, nsnull)
STYLE_STRUCT_INHERITED(SVG, nsnull, ())
#endif
#ifdef UNDEF_STYLE_STRUCT_INHERITED

View File

@ -42,6 +42,7 @@
#include "nsString.h"
#include "nsUnitConversion.h"
#include "nsIPresContext.h"
#include "nsIDeviceContext.h"
#include "nsIStyleRule.h"
#include "nsISupportsArray.h"
#include "nsCRT.h"
@ -230,6 +231,17 @@ nsStyleFont::nsStyleFont(const nsStyleFont& aSrc)
{
}
nsStyleFont::nsStyleFont(nsIPresContext* aPresContext)
: mFlags(NS_STYLE_FONT_DEFAULT)
{
const nsFont* defaultFont;
aPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID,
&defaultFont);
mFont = *defaultFont;
mSize = mFont.size = nsStyleFont::ZoomText(aPresContext, mFont.size);
}
void*
nsStyleFont::operator new(size_t sz, nsIPresContext* aContext) CPP_THROW_NEW {
void* result = nsnull;
@ -253,6 +265,28 @@ nsChangeHint nsStyleFont::CalcDifference(const nsStyleFont& aOther) const
return NS_STYLE_HINT_REFLOW;
}
inline float
TextZoomFor(nsIPresContext* aPresContext)
{
nsCOMPtr<nsIDeviceContext> dc;
aPresContext->GetDeviceContext(getter_AddRefs(dc));
float textZoom;
dc->GetTextZoom(textZoom);
return textZoom;
}
/* static */ nscoord
nsStyleFont::ZoomText(nsIPresContext *aPresContext, nscoord aSize)
{
return nscoord(float(aSize) * TextZoomFor(aPresContext));
}
/* static */ nscoord
nsStyleFont::UnZoomText(nsIPresContext *aPresContext, nscoord aSize)
{
return nscoord(float(aSize) / TextZoomFor(aPresContext));
}
nsChangeHint nsStyleFont::CalcFontDifference(const nsFont& aFont1, const nsFont& aFont2)
{
if ((aFont1.size == aFont2.size) &&
@ -1004,6 +1038,8 @@ nsChangeHint nsStyleBackground::CalcDifference(const nsStyleBackground& aOther)
&& ((NS_STYLE_BG_ATTACHMENT_FIXED == mBackgroundAttachment) ||
(NS_STYLE_BG_ATTACHMENT_FIXED == aOther.mBackgroundAttachment)))
// this might require creation of a view
// XXX This probably doesn't call ApplyRenderingChangeToTree, which
// means we might not invalidate the canvas if this is the body.
return NS_STYLE_HINT_FRAMECHANGE;
if ((mBackgroundAttachment == aOther.mBackgroundAttachment) &&

View File

@ -579,7 +579,12 @@ public:
NS_IMETHOD DidSetStyleContext(nsIPresContext* aPresContext) = 0;
/**
* Get the style data associated with this frame.
* Get the style data associated with this frame. This fills in a
* const style struct pointer that should never be modified. See
* |nsIStyleContext::GetStyleData| for more information.
*
* The use of the typesafe global helper function |GetStyleData|,
* below, is preferred to direct use of this function.
*/
NS_IMETHOD GetStyleDataExternal(nsStyleStructID aSID,
const nsStyleStruct*& aStyleStruct) const = 0;

View File

@ -58,6 +58,7 @@ class nsIFrameManager;
class nsISupportsArray;
class nsRuleNode;
struct nsFindFrameHint;
struct nsCachedStyleData;
#include "nsVoidArray.h"
@ -125,6 +126,10 @@ public:
virtual nsresult BeginRuleTreeReconstruct()=0;
virtual nsresult EndRuleTreeReconstruct()=0;
// For getting the cached default data in case we hit out-of-memory.
// To be used only by nsRuleNode.
virtual nsCachedStyleData* GetDefaultStyleData() = 0;
virtual nsresult GetStyleFrameConstruction(nsIStyleFrameConstruction** aResult) = 0;
// ClearCachedStyleData is used to invalidate portions of both the style context tree

View File

@ -579,7 +579,12 @@ public:
NS_IMETHOD DidSetStyleContext(nsIPresContext* aPresContext) = 0;
/**
* Get the style data associated with this frame.
* Get the style data associated with this frame. This fills in a
* const style struct pointer that should never be modified. See
* |nsIStyleContext::GetStyleData| for more information.
*
* The use of the typesafe global helper function |GetStyleData|,
* below, is preferred to direct use of this function.
*/
NS_IMETHOD GetStyleDataExternal(nsStyleStructID aSID,
const nsStyleStruct*& aStyleStruct) const = 0;

View File

@ -416,9 +416,9 @@ nsRuleNode::Destroy()
mPresContext->FreeToShell(sizeof(nsRuleNode), this);
}
void nsRuleNode::CreateRootNode(nsIPresContext* aPresContext, nsRuleNode** aResult)
nsRuleNode* nsRuleNode::CreateRootNode(nsIPresContext* aPresContext)
{
*aResult = new (aPresContext) nsRuleNode(aPresContext);
return new (aPresContext) nsRuleNode(aPresContext, nsnull, nsnull);
}
nsILanguageAtomService* nsRuleNode::gLangService = nsnull;
@ -555,6 +555,8 @@ nsRuleNode::PathContainsRule(nsIStyleRule* aRule, PRBool* aMatched)
nsresult
nsRuleNode::ClearCachedData(nsIStyleRule* aRule)
{
NS_ASSERTION(aRule, "you should be using ClearCachedDataInSubtree");
nsRuleNode* ruleDest = this;
while (ruleDest) {
if (ruleDest->mRule == aRule)
@ -563,6 +565,8 @@ nsRuleNode::ClearCachedData(nsIStyleRule* aRule)
}
if (ruleDest) {
NS_ASSERTION(ruleDest->mParent, "node must not be root");
// The rule was contained along our branch. We need to blow away
// all cached data along this path. Note that, because of the definition
// of inline style, all nodes along this path must have exactly one child. This
@ -603,8 +607,10 @@ nsRuleNode::ClearCachedDataInSubtree(nsIStyleRule* aRule)
// We have a match. Blow away all data stored at this node.
if (mStyleData.mResetData || mStyleData.mInheritedData)
mStyleData.Destroy(0, mPresContext);
mNoneBits &= ~NS_STYLE_INHERIT_MASK;
mDependentBits &= ~NS_STYLE_INHERIT_MASK;
aRule = nsnull; // Cause everything to be blown away in the descendants.
}
@ -980,7 +986,7 @@ static const PropertyCheckData SVGCheckProperties[] = {
static const StructCheckData gCheckProperties[] = {
#define STYLE_STRUCT(name, checkdata_cb) \
#define STYLE_STRUCT(name, checkdata_cb, ctor_args) \
{name##CheckProperties, \
sizeof(name##CheckProperties)/sizeof(PropertyCheckData), \
checkdata_cb},
@ -1608,16 +1614,6 @@ nsRuleNode::WalkRuleTree(const nsStyleStructID aSID,
return res;
}
static nscoord
ZoomFont(nsIPresContext* aPresContext, nscoord aInSize)
{
nsCOMPtr<nsIDeviceContext> dc;
aPresContext->GetDeviceContext(getter_AddRefs(dc));
float textZoom;
dc->GetTextZoom(textZoom);
return nscoord(aInSize * textZoom);
}
static PRBool
IsChrome(nsIPresContext* aPresContext)
{
@ -1643,10 +1639,7 @@ nsRuleNode::SetDefaultOnRoot(const nsStyleStructID aSID, nsStyleContext* aContex
switch (aSID) {
case eStyleStruct_Font:
{
const nsFont* defaultFont;
mPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID, &defaultFont);
nsStyleFont* fontData = new (mPresContext) nsStyleFont(*defaultFont);
fontData->mSize = ZoomFont(mPresContext, fontData->mFont.size);
nsStyleFont* fontData = new (mPresContext) nsStyleFont(mPresContext);
nscoord minimumFontSize = 0;
mPresContext->GetCachedIntPref(kPresContext_MinimumFontSize, minimumFontSize);
@ -1792,7 +1785,7 @@ nsRuleNode::SetDefaultOnRoot(const nsStyleStructID aSID, nsStyleContext* aContex
nsRuleNode::ComputeStyleDataFn
nsRuleNode::gComputeStyleDataFn[] = {
#define STYLE_STRUCT(name, checkdata_cb) \
#define STYLE_STRUCT(name, checkdata_cb, ctor_args) \
&nsRuleNode::Compute##name##Data,
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
@ -1805,7 +1798,7 @@ SetFont(nsIPresContext* aPresContext, nsStyleContext* aContext,
nscoord aMinFontSize, PRBool aUseDocumentFonts, PRBool aChromeOverride,
PRBool aIsGeneric, const nsRuleDataFont& aFontData,
const nsFont& aDefaultFont, const nsStyleFont* aParentFont,
nsStyleFont* aFont, PRBool aZoom, PRBool& aInherited)
nsStyleFont* aFont, PRBool& aInherited)
{
const nsFont* defaultVariableFont;
const nsFont* defaultFixedFont;
@ -1863,7 +1856,9 @@ SetFont(nsIPresContext* aPresContext, nsStyleContext* aContext,
if (NS_FAILED(dc->GetSystemFont(sysID, &aFont->mFont))) {
aFont->mFont.name = defaultVariableFont->name;
}
aFont->mSize = aFont->mFont.size; // this becomes our cascading size
// this becomes our cascading size
aFont->mSize = aFont->mFont.size
= nsStyleFont::ZoomText(aPresContext, aFont->mFont.size);
}
aFont->mFont.familyNameQuirks = PR_FALSE;
@ -1964,7 +1959,7 @@ SetFont(nsIPresContext* aPresContext, nsStyleContext* aContext,
}
// font-size: enum, length, percent, inherit
PRBool zoom = aZoom;
PRBool zoom = PR_FALSE;
if (eCSSUnit_Enumerated == aFontData.mSize.GetUnit()) {
PRInt32 value = aFontData.mSize.GetIntValue();
PRInt32 scaler;
@ -1987,12 +1982,8 @@ SetFont(nsIPresContext* aPresContext, nsStyleContext* aContext,
// Un-zoom so we use the tables correctly. We'll then rezoom due
// to the |zoom = PR_TRUE| above.
nsCOMPtr<nsIDeviceContext> dc;
aPresContext->GetDeviceContext(getter_AddRefs(dc));
float textZoom;
dc->GetTextZoom(textZoom);
nscoord parentSize = nscoord(aParentFont->mSize / textZoom);
nscoord parentSize =
nsStyleFont::UnZoomText(aPresContext, aParentFont->mSize);
if (NS_STYLE_FONT_SIZE_LARGER == value) {
PRInt32 index = nsStyleUtil::FindNextLargerFontSize(parentSize, (PRInt32)aDefaultFont.size,
@ -2058,7 +2049,7 @@ SetFont(nsIPresContext* aPresContext, nsStyleContext* aContext,
// We want to zoom the cascaded size so that em-based measurements,
// line-heights, etc., work.
if (zoom)
aFont->mSize = ZoomFont(aPresContext, aFont->mSize);
aFont->mSize = nsStyleFont::ZoomText(aPresContext, aFont->mSize);
// enforce the user' specified minimum font-size on the value that we expose
if (aChromeOverride) {
@ -2116,8 +2107,9 @@ SetGenericFont(nsIPresContext* aPresContext, nsStyleContext* aContext,
const nsFont* defaultFont;
aPresContext->GetDefaultFont(aGenericFontID, &defaultFont);
nsStyleFont parentFont(*defaultFont);
parentFont.mSize = parentFont.mFont.size
= nsStyleFont::ZoomText(aPresContext, parentFont.mSize);
PRInt32 i = contextPath.Count() - 1;
PRBool zoom = PR_TRUE;
if (higherContext) {
nsStyleContext* context = (nsStyleContext*)contextPath[i];
nsStyleFont* tmpFont = (nsStyleFont*)context->GetStyleData(eStyleStruct_Font);
@ -2125,7 +2117,6 @@ SetGenericFont(nsIPresContext* aPresContext, nsStyleContext* aContext,
parentFont.mFont = tmpFont->mFont;
parentFont.mSize = tmpFont->mSize;
--i;
zoom = PR_FALSE;
}
aFont->mFlags = parentFont.mFlags;
aFont->mFont = parentFont.mFont;
@ -2163,7 +2154,7 @@ SetGenericFont(nsIPresContext* aPresContext, nsStyleContext* aContext,
SetFont(aPresContext, context, aMinFontSize,
aUseDocumentFonts, aChromeOverride, PR_TRUE,
fontData, *defaultFont, &parentFont, aFont, zoom, dummy);
fontData, *defaultFont, &parentFont, aFont, dummy);
// XXX Not sure if we need to do this here
// If we have a post-resolve callback, handle that now.
@ -2173,7 +2164,6 @@ SetGenericFont(nsIPresContext* aPresContext, nsStyleContext* aContext,
parentFont.mFlags = aFont->mFlags;
parentFont.mFont = aFont->mFont;
parentFont.mSize = aFont->mSize;
zoom = PR_FALSE;
}
// Finish off by applying our own rules. In this case, aFontData
@ -2181,7 +2171,7 @@ SetGenericFont(nsIPresContext* aPresContext, nsStyleContext* aContext,
// can just compute the delta from the parent.
SetFont(aPresContext, aContext, aMinFontSize,
aUseDocumentFonts, aChromeOverride, PR_TRUE,
aFontData, *defaultFont, &parentFont, aFont, zoom, dummy);
aFontData, *defaultFont, &parentFont, aFont, dummy);
}
const nsStyleStruct*
@ -2222,12 +2212,8 @@ nsRuleNode::ComputeFontData(nsStyleStruct* aStartStruct,
}
}
PRBool zoom = PR_FALSE;
const nsFont* defaultFont;
if (!font) {
mPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID, &defaultFont);
font = new (mPresContext) nsStyleFont(*defaultFont);
zoom = PR_TRUE;
font = new (mPresContext) nsStyleFont(mPresContext);
}
if (!parentFont)
parentFont = font;
@ -2268,6 +2254,8 @@ nsRuleNode::ComputeFontData(nsStyleStruct* aStartStruct,
// determine if we have to override the minimum font-size constraint.
if (!useDocumentFonts || minimumFontSize > 0) {
chromeOverride = IsChrome(mPresContext);
// XXXldb Just fix up |useDocumentFonts| here and drop the
// |chromeOverride| variable from here on!
}
// If we don't have to use document fonts, then we are only entitled
@ -2282,10 +2270,11 @@ nsRuleNode::ComputeFontData(nsStyleStruct* aStartStruct,
// continue the normal processing
// our default font is the most recent generic font
generic = parentFont->mFlags & NS_STYLE_FONT_FACE_MASK;
const nsFont* defaultFont;
mPresContext->GetDefaultFont(generic, &defaultFont);
SetFont(mPresContext, aContext, minimumFontSize,
useDocumentFonts, chromeOverride, PR_FALSE,
fontData, *defaultFont, parentFont, font, zoom, inherited);
fontData, *defaultFont, parentFont, font, inherited);
}
else {
// re-calculate the font as a generic font
@ -2368,8 +2357,8 @@ nsRuleNode::ComputeTextData(nsStyleStruct* aStartStruct,
aContext, mPresContext, inherited);
if (textData.mLineHeight.IsFixedLengthUnit() ||
textData.mLineHeight.GetUnit() == eCSSUnit_Pixel)
text->mLineHeight.SetCoordValue(
ZoomFont(mPresContext, text->mLineHeight.GetCoordValue()));
text->mLineHeight.SetCoordValue(nsStyleFont::ZoomText(mPresContext,
text->mLineHeight.GetCoordValue()));
}
@ -4637,24 +4626,31 @@ nsRuleNode::ComputeSVGData(nsStyleStruct* aStartStruct,
inline const nsStyleStruct*
nsRuleNode::GetParentData(const nsStyleStructID aSID)
{
nsRuleNode* ruleNode = mParent;
nsStyleStruct* currStruct = nsnull;
while (ruleNode) {
currStruct = ruleNode->mStyleData.GetStyleData(aSID);
if (currStruct)
break; // We found a rule with fully specified data. We don't need to go up
// the tree any further, since the remainder of this branch has already
// been computed.
ruleNode = ruleNode->mParent; // Climb up to the next rule in the tree (a less specific rule).
}
// Walk up the rule tree from this rule node (towards less specific
// rules).
for (nsRuleNode* ruleNode = mParent; ruleNode; ruleNode = ruleNode->mParent)
{
const nsStyleStruct *currStruct = ruleNode->mStyleData.GetStyleData(aSID);
if (currStruct) {
// We found a rule with fully specified data. We don't need to go
// up the tree any further, since the remainder of this branch has
// already been computed.
return currStruct;
}
NS_ASSERTION(ruleNode->mDependentBits &
nsCachedStyleData::GetBitForSID(aSID),
"dependent bits improperly set");
}
return currStruct; // Just return whatever we found.
NS_NOTREACHED("dependent bits set on root or improperly set");
return nsnull;
}
nsRuleNode::GetStyleDataFn
nsRuleNode::gGetStyleDataFn[] = {
#define STYLE_STRUCT(name, checkdata_cb) &nsRuleNode::Get##name##Data,
#define STYLE_STRUCT(name, checkdata_cb, ctor_args) \
&nsRuleNode::Get##name##Data,
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
@ -4666,21 +4662,42 @@ nsRuleNode::GetStyleData(nsStyleStructID aSID,
nsStyleContext* aContext,
PRBool aComputeData)
{
const nsStyleStruct* cachedData = mStyleData.GetStyleData(aSID);
if (cachedData)
return cachedData; // We have a fully specified struct. Just return it.
const nsStyleStruct* data = mStyleData.GetStyleData(aSID);
if (data)
return data; // We have a fully specified struct. Just return it.
if (mDependentBits & nsCachedStyleData::GetBitForSID(aSID))
return GetParentData(aSID); // We depend on an ancestor for this
// struct since the cached struct it has
// is also appropriate for this rule
// node. Just go up the rule tree and
// return the first cached struct we
// find.
if (mDependentBits & nsCachedStyleData::GetBitForSID(aSID)) {
// We depend on an ancestor for this struct since the cached struct
// it has is also appropriate for this rule node. Just go up the
// rule tree and return the first cached struct we find.
data = GetParentData(aSID);
if (data)
return data;
NS_NOTREACHED("dependent bits set but no cached struct present");
}
// Nothing is cached. We'll have to delve further and examine our rules.
GetStyleDataFn fn = gGetStyleDataFn[aSID];
return fn ? (this->*fn)(aContext, aComputeData) : nsnull;
if (!fn) {
NS_NOTREACHED("unknown style struct requested");
return nsnull;
}
data = (this->*fn)(aContext, aComputeData);
if (data || !aComputeData)
return data;
NS_NOTREACHED("could not create style struct");
// To ensure that |GetStyleData| never returns null (even when we're
// out of memory), we'll get the style set and get a copy of the
// default values for the given style struct from the set. Note that
// this works fine even if |this| is a rule node that has been
// destroyed (leftover from a previous rule tree) but is somehow still
// used.
nsCOMPtr<nsIPresShell> shell;
mPresContext->GetShell(getter_AddRefs(shell));
nsCOMPtr<nsIStyleSet> set;
shell->GetStyleSet(getter_AddRefs(set));
return set->GetDefaultStyleData()->GetStyleData(aSID);
}
void

View File

@ -57,9 +57,9 @@ typedef void (*nsPostResolveFunc)(nsStyleStruct* aStyleStruct, nsRuleData* aData
struct nsInheritedStyleData
{
#define STYLE_STRUCT_INHERITED(name, checkdata_cb) \
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args) \
nsStyle##name * m##name##Data;
#define STYLE_STRUCT_RESET(name, checkdata_cb)
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args)
#include "nsStyleStructList.h"
@ -73,10 +73,10 @@ struct nsInheritedStyleData
};
void ClearInheritedData(PRUint32 aBits) {
#define STYLE_STRUCT_INHERITED(name, checkdata_cb) \
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args) \
if (m##name##Data && (aBits & NS_STYLE_INHERIT_BIT(name))) \
m##name##Data = nsnull;
#define STYLE_STRUCT_RESET(name, checkdata_cb)
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args)
#include "nsStyleStructList.h"
@ -85,10 +85,10 @@ struct nsInheritedStyleData
};
void Destroy(PRUint32 aBits, nsIPresContext* aContext) {
#define STYLE_STRUCT_INHERITED(name, checkdata_cb) \
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args) \
if (m##name##Data && !(aBits & NS_STYLE_INHERIT_BIT(name))) \
m##name##Data->Destroy(aContext);
#define STYLE_STRUCT_RESET(name, checkdata_cb)
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args)
#include "nsStyleStructList.h"
@ -99,9 +99,9 @@ struct nsInheritedStyleData
};
nsInheritedStyleData() {
#define STYLE_STRUCT_INHERITED(name, checkdata_cb) \
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args) \
m##name##Data = nsnull;
#define STYLE_STRUCT_RESET(name, checkdata_cb)
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args)
#include "nsStyleStructList.h"
@ -115,9 +115,9 @@ struct nsResetStyleData
{
nsResetStyleData()
{
#define STYLE_STRUCT_RESET(name, checkdata_cb) \
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args) \
m##name##Data = nsnull;
#define STYLE_STRUCT_INHERITED(name, checkdata_cb)
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args)
#include "nsStyleStructList.h"
@ -132,10 +132,10 @@ struct nsResetStyleData
}
void ClearInheritedData(PRUint32 aBits) {
#define STYLE_STRUCT_RESET(name, checkdata_cb) \
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args) \
if (m##name##Data && (aBits & NS_STYLE_INHERIT_BIT(name))) \
m##name##Data = nsnull;
#define STYLE_STRUCT_INHERITED(name, checkdata_cb)
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args)
#include "nsStyleStructList.h"
@ -144,10 +144,10 @@ struct nsResetStyleData
};
void Destroy(PRUint32 aBits, nsIPresContext* aContext) {
#define STYLE_STRUCT_RESET(name, checkdata_cb) \
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args) \
if (m##name##Data && !(aBits & NS_STYLE_INHERIT_BIT(name))) \
m##name##Data->Destroy(aContext);
#define STYLE_STRUCT_INHERITED(name, checkdata_cb)
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args)
#include "nsStyleStructList.h"
@ -157,9 +157,9 @@ struct nsResetStyleData
aContext->FreeToShell(sizeof(nsResetStyleData), this);
};
#define STYLE_STRUCT_RESET(name, checkdata_cb) \
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args) \
nsStyle##name * m##name##Data;
#define STYLE_STRUCT_INHERITED(name, checkdata_cb)
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args)
#include "nsStyleStructList.h"
@ -542,10 +542,11 @@ protected:
static GetStyleDataFn gGetStyleDataFn[];
public:
nsRuleNode(nsIPresContext* aPresContext, nsIStyleRule* aRule=nsnull, nsRuleNode* aParent=nsnull);
nsRuleNode(nsIPresContext* aPresContext, nsIStyleRule* aRule,
nsRuleNode* aParent);
virtual ~nsRuleNode();
static void CreateRootNode(nsIPresContext* aPresContext, nsRuleNode** aResult);
static nsRuleNode* CreateRootNode(nsIPresContext* aPresContext);
nsresult GetBits(PRInt32 aType, PRUint32* aResult);
nsresult Transition(nsIStyleRule* aRule, nsRuleNode** aResult);

View File

@ -98,7 +98,27 @@ public:
*/
void Mark();
/*
* Get the style data for a style struct. This is the most important
* member function of nsIStyleContext. It fills in a const pointer
* to a style data struct that is appropriate for the style context's
* frame. This struct may be shared with other contexts (either in
* the rule tree or the style context tree), so it should not be
* modified.
*
* This function will NOT return null (even when out of memory) when
* given a valid style struct ID, so the result does not need to be
* null-checked.
*
* The typesafe global helper function |GetStyleData| (below) is
* preferred to the use of this function (and is a simple typesafe
* wrapper for this function).
*
* See also |nsIFrame::GetStyleData| and the other global
* |GetStyleData| in nsIFrame.h.
*/
const nsStyleStruct* GetStyleData(nsStyleStructID aSID);
const nsStyleStruct* PeekStyleData(nsStyleStructID aSID);
nsStyleStruct* GetUniqueStyleData(nsIPresContext* aPresContext, const nsStyleStructID& aSID);

View File

@ -189,6 +189,10 @@ public:
virtual nsresult BeginRuleTreeReconstruct();
virtual nsresult EndRuleTreeReconstruct();
// For getting the cached default data in case we hit out-of-memory.
// To be used only by nsRuleNode.
virtual nsCachedStyleData* GetDefaultStyleData();
virtual nsresult GetRuleTree(nsRuleNode** aResult);
virtual nsresult ClearCachedDataInRuleTree(nsIStyleRule* aRule);
@ -319,6 +323,9 @@ protected:
void EnsureRuleWalker(nsIPresContext* aPresContext);
// Returns false on out-of-memory.
PRBool BuildDefaultStyleData(nsIPresContext* aPresContext);
void ClearRuleProcessors(void);
void ClearAgentRuleProcessors(void);
void ClearUserRuleProcessors(void);
@ -365,6 +372,11 @@ protected:
nsCOMPtr<nsIStyleRuleSupplier> mStyleRuleSupplier;
// To be used only in case of emergency, such as being out of memory
// or operating on a deleted rule node. The latter should never
// happen, of course.
nsCachedStyleData mDefaultStyleData;
nsRuleNode* mRuleTree; // This is the root of our rule tree. It is a lexicographic tree of
// matched rules that style contexts use to look up properties.
nsRuleNode* mOldRuleTree; // Used during rule tree reconstruction.
@ -1143,25 +1155,55 @@ StyleSetImpl::WalkRuleProcessors(nsISupportsArrayEnumFunc aFunc,
mOverrideRuleProcessors->EnumerateForwards(aFunc, aData);
}
#ifdef NS_DEBUG
#define NS_ASSERT_REFCOUNT(ptr,cnt,msg) { \
nsrefcnt count = ptr->AddRef(); \
ptr->Release(); \
NS_ASSERTION(--count == cnt, msg); \
}
#else
#define NS_ASSERT_REFCOUNT(ptr,cnt,msg) {}
#endif
void StyleSetImpl::EnsureRuleWalker(nsIPresContext* aPresContext)
{
{
if (mRuleWalker)
return;
nsRuleNode::CreateRootNode(aPresContext, &mRuleTree);
if (!mDefaultStyleData.mResetData && !BuildDefaultStyleData(aPresContext)) {
mDefaultStyleData.Destroy(0, aPresContext);
return;
}
mRuleTree = nsRuleNode::CreateRootNode(aPresContext);
if (!mRuleTree)
return;
mRuleWalker = new nsRuleWalker(mRuleTree);
}
PRBool StyleSetImpl::BuildDefaultStyleData(nsIPresContext* aPresContext)
{
NS_ASSERTION(!mDefaultStyleData.mResetData &&
!mDefaultStyleData.mInheritedData,
"leaking default style data");
mDefaultStyleData.mResetData = new (aPresContext) nsResetStyleData;
if (!mDefaultStyleData.mResetData)
return PR_FALSE;
mDefaultStyleData.mInheritedData = new (aPresContext) nsInheritedStyleData;
if (!mDefaultStyleData.mInheritedData)
return PR_FALSE;
#define SSARG_PRESCONTEXT aPresContext
#define CREATE_DATA(name, type, args) \
if (!(mDefaultStyleData.m##type##Data->m##name##Data = \
new (aPresContext) nsStyle##name args)) \
return PR_FALSE;
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args) \
CREATE_DATA(name, Inherited, ctor_args)
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args) \
CREATE_DATA(name, Reset, ctor_args)
#include "nsStyleStructList.h"
#undef STYLE_STRUCT_INHERITED
#undef STYLE_STRUCT_RESET
#undef SSARG_PRESCONTEXT
return PR_TRUE;
}
already_AddRefed<nsStyleContext>
StyleSetImpl::ResolveStyleFor(nsIPresContext* aPresContext,
nsIContent* aContent,
@ -1184,6 +1226,7 @@ StyleSetImpl::ResolveStyleFor(nsIPresContext* aPresContext,
mDocRuleProcessors ||
mOverrideRuleProcessors) {
EnsureRuleWalker(aPresContext);
NS_ENSURE_TRUE(mRuleWalker, nsnull);
nsCOMPtr<nsIAtom> medium;
aPresContext->GetMedium(getter_AddRefs(medium));
RulesMatchingData data(aPresContext, medium, aContent, mRuleWalker);
@ -1218,6 +1261,7 @@ StyleSetImpl::ResolveStyleForNonElement(nsIPresContext* aPresContext,
mDocRuleProcessors ||
mOverrideRuleProcessors) {
EnsureRuleWalker(aPresContext);
NS_ENSURE_TRUE(mRuleWalker, nsnull);
result = GetContext(aPresContext, aParentContext,
nsCSSAnonBoxes::mozNonElement).get();
NS_ASSERTION(mRuleWalker->AtRoot(), "rule walker must be at root");
@ -1282,6 +1326,7 @@ StyleSetImpl::ResolvePseudoStyleFor(nsIPresContext* aPresContext,
nsCOMPtr<nsIAtom> medium;
aPresContext->GetMedium(getter_AddRefs(medium));
EnsureRuleWalker(aPresContext);
NS_ENSURE_TRUE(mRuleWalker, nsnull);
PseudoRulesMatchingData data(aPresContext, medium, aParentContent,
aPseudoTag, aComparator, mRuleWalker);
FileRules(EnumPseudoRulesMatching, &data);
@ -1324,6 +1369,7 @@ StyleSetImpl::ProbePseudoStyleFor(nsIPresContext* aPresContext,
nsCOMPtr<nsIAtom> medium;
aPresContext->GetMedium(getter_AddRefs(medium));
EnsureRuleWalker(aPresContext);
NS_ENSURE_TRUE(mRuleWalker, nsnull);
PseudoRulesMatchingData data(aPresContext, medium, aParentContent,
aPseudoTag, nsnull, mRuleWalker);
FileRules(EnumPseudoRulesMatching, &data);
@ -1378,11 +1424,15 @@ NS_IMETHODIMP
StyleSetImpl::Shutdown(nsIPresContext* aPresContext)
{
delete mRuleWalker;
mRuleWalker = nsnull;
if (mRuleTree)
{
mRuleTree->Destroy();
mRuleTree = nsnull;
}
mDefaultStyleData.Destroy(0, aPresContext);
return NS_OK;
}
@ -1450,6 +1500,12 @@ StyleSetImpl::EndRuleTreeReconstruct()
return NS_OK;
}
nsCachedStyleData*
StyleSetImpl::GetDefaultStyleData()
{
return &mDefaultStyleData;
}
nsresult
StyleSetImpl::ClearCachedDataInRuleTree(nsIStyleRule* aInlineStyleRule)
{
@ -1507,6 +1563,7 @@ StyleSetImpl::ReParentStyleContext(nsIPresContext* aPresContext,
nsRuleNode* ruleNode;
aStyleContext->GetRuleNode(&ruleNode);
EnsureRuleWalker(aPresContext);
NS_ENSURE_TRUE(mRuleWalker, nsnull);
mRuleWalker->SetCurrentNode(ruleNode);
already_AddRefed<nsStyleContext> result =
@ -1845,14 +1902,9 @@ void StyleSetImpl::ListContexts(nsIFrame* aRootFrame, FILE* out, PRInt32 aIndent
nsresult
NS_NewStyleSet(nsIStyleSet** aInstancePtrResult)
{
if (!aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
StyleSetImpl *it = new StyleSetImpl();
if (!it) {
StyleSetImpl *it = new StyleSetImpl();
if (!it)
return NS_ERROR_OUT_OF_MEMORY;
}
return CallQueryInterface(it, aInstancePtrResult);
}

View File

@ -42,6 +42,7 @@
#include "nsString.h"
#include "nsUnitConversion.h"
#include "nsIPresContext.h"
#include "nsIDeviceContext.h"
#include "nsIStyleRule.h"
#include "nsISupportsArray.h"
#include "nsCRT.h"
@ -230,6 +231,17 @@ nsStyleFont::nsStyleFont(const nsStyleFont& aSrc)
{
}
nsStyleFont::nsStyleFont(nsIPresContext* aPresContext)
: mFlags(NS_STYLE_FONT_DEFAULT)
{
const nsFont* defaultFont;
aPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID,
&defaultFont);
mFont = *defaultFont;
mSize = mFont.size = nsStyleFont::ZoomText(aPresContext, mFont.size);
}
void*
nsStyleFont::operator new(size_t sz, nsIPresContext* aContext) CPP_THROW_NEW {
void* result = nsnull;
@ -253,6 +265,28 @@ nsChangeHint nsStyleFont::CalcDifference(const nsStyleFont& aOther) const
return NS_STYLE_HINT_REFLOW;
}
inline float
TextZoomFor(nsIPresContext* aPresContext)
{
nsCOMPtr<nsIDeviceContext> dc;
aPresContext->GetDeviceContext(getter_AddRefs(dc));
float textZoom;
dc->GetTextZoom(textZoom);
return textZoom;
}
/* static */ nscoord
nsStyleFont::ZoomText(nsIPresContext *aPresContext, nscoord aSize)
{
return nscoord(float(aSize) * TextZoomFor(aPresContext));
}
/* static */ nscoord
nsStyleFont::UnZoomText(nsIPresContext *aPresContext, nscoord aSize)
{
return nscoord(float(aSize) / TextZoomFor(aPresContext));
}
nsChangeHint nsStyleFont::CalcFontDifference(const nsFont& aFont1, const nsFont& aFont2)
{
if ((aFont1.size == aFont2.size) &&
@ -1004,6 +1038,8 @@ nsChangeHint nsStyleBackground::CalcDifference(const nsStyleBackground& aOther)
&& ((NS_STYLE_BG_ATTACHMENT_FIXED == mBackgroundAttachment) ||
(NS_STYLE_BG_ATTACHMENT_FIXED == aOther.mBackgroundAttachment)))
// this might require creation of a view
// XXX This probably doesn't call ApplyRenderingChangeToTree, which
// means we might not invalidate the canvas if this is the body.
return NS_STYLE_HINT_FRAMECHANGE;
if ((mBackgroundAttachment == aOther.mBackgroundAttachment) &&

View File

@ -64,7 +64,7 @@ enum nsStyleStructID {
* increase by 1.
*/
#define STYLE_STRUCT(name, checkdata_cb) eStyleStruct_##name,
#define STYLE_STRUCT(name, checkdata_cb, ctor_args) eStyleStruct_##name,
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
@ -96,12 +96,18 @@ struct nsStyleStruct {
struct nsStyleFont : public nsStyleStruct {
nsStyleFont(void);
nsStyleFont(const nsFont& aFont);
nsStyleFont(const nsStyleFont& aStyleFont);
nsStyleFont(nsIPresContext *aPresContext);
~nsStyleFont(void) {};
NS_DEFINE_STATIC_STYLESTRUCTID_ACCESSOR(eStyleStruct_Font)
nsChangeHint CalcDifference(const nsStyleFont& aOther) const;
static nsChangeHint CalcFontDifference(const nsFont& aFont1, const nsFont& aFont2);
static nscoord ZoomText(nsIPresContext* aPresContext, nscoord aSize);
static nscoord UnZoomText(nsIPresContext* aPresContext, nscoord aSize);
void* operator new(size_t sz, nsIPresContext* aContext) CPP_THROW_NEW;
void Destroy(nsIPresContext* aContext);
@ -112,10 +118,6 @@ struct nsStyleFont : public nsStyleStruct {
// which is our "actual size" and is enforced to be >= the user's
// preferred min-size. mFont.size should be used for display purposes
// while mSize is the value to return in getComputedStyle() for example.
nsStyleFont(const nsFont& aFont);
nsStyleFont(const nsStyleFont& aStyleFont);
nsStyleFont(nsIPresContext* aPresContext);
};
struct nsStyleColor : public nsStyleStruct {

View File

@ -44,40 +44,41 @@
*/
#ifndef STYLE_STRUCT_INHERITED
#define STYLE_STRUCT_INHERITED(name, checkdata_cb) \
STYLE_STRUCT(name, checkdata_cb)
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args) \
STYLE_STRUCT(name, checkdata_cb, ctor_args)
#define UNDEF_STYLE_STRUCT_INHERITED
#endif
#ifndef STYLE_STRUCT_RESET
#define STYLE_STRUCT_RESET(name, checkdata_cb) STYLE_STRUCT(name, checkdata_cb)
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args) \
STYLE_STRUCT(name, checkdata_cb, ctor_args)
#define UNDEF_STYLE_STRUCT_RESET
#endif
STYLE_STRUCT_INHERITED(Font, CheckFontCallback)
STYLE_STRUCT_INHERITED(Color, nsnull)
STYLE_STRUCT_RESET(Background, nsnull)
STYLE_STRUCT_INHERITED(List, nsnull)
STYLE_STRUCT_RESET(Position, nsnull)
STYLE_STRUCT_INHERITED(Text, nsnull)
STYLE_STRUCT_RESET(TextReset, nsnull)
STYLE_STRUCT_RESET(Display, nsnull)
STYLE_STRUCT_INHERITED(Visibility, nsnull)
STYLE_STRUCT_RESET(Content, nsnull)
STYLE_STRUCT_INHERITED(Quotes, nsnull)
STYLE_STRUCT_INHERITED(UserInterface, nsnull)
STYLE_STRUCT_RESET(UIReset, nsnull)
STYLE_STRUCT_RESET(Table, nsnull)
STYLE_STRUCT_INHERITED(TableBorder, nsnull)
STYLE_STRUCT_RESET(Margin, nsnull)
STYLE_STRUCT_RESET(Padding, nsnull)
STYLE_STRUCT_RESET(Border, nsnull)
STYLE_STRUCT_RESET(Outline, nsnull)
STYLE_STRUCT_INHERITED(Font, CheckFontCallback, (SSARG_PRESCONTEXT))
STYLE_STRUCT_INHERITED(Color, nsnull, (SSARG_PRESCONTEXT))
STYLE_STRUCT_RESET(Background, nsnull, (SSARG_PRESCONTEXT))
STYLE_STRUCT_INHERITED(List, nsnull, ())
STYLE_STRUCT_RESET(Position, nsnull, ())
STYLE_STRUCT_INHERITED(Text, nsnull, ())
STYLE_STRUCT_RESET(TextReset, nsnull, ())
STYLE_STRUCT_RESET(Display, nsnull, ())
STYLE_STRUCT_INHERITED(Visibility, nsnull, (SSARG_PRESCONTEXT))
STYLE_STRUCT_RESET(Content, nsnull, ())
STYLE_STRUCT_INHERITED(Quotes, nsnull, ())
STYLE_STRUCT_INHERITED(UserInterface, nsnull, ())
STYLE_STRUCT_RESET(UIReset, nsnull, ())
STYLE_STRUCT_RESET(Table, nsnull, ())
STYLE_STRUCT_INHERITED(TableBorder, nsnull, (SSARG_PRESCONTEXT))
STYLE_STRUCT_RESET(Margin, nsnull, ())
STYLE_STRUCT_RESET(Padding, nsnull, ())
STYLE_STRUCT_RESET(Border, nsnull, ())
STYLE_STRUCT_RESET(Outline, nsnull, (SSARG_PRESCONTEXT))
#ifdef INCLUDE_XUL
STYLE_STRUCT_RESET(XUL, nsnull)
STYLE_STRUCT_RESET(XUL, nsnull, ())
#endif
#ifdef MOZ_SVG
STYLE_STRUCT_INHERITED(SVG, nsnull)
STYLE_STRUCT_INHERITED(SVG, nsnull, ())
#endif
#ifdef UNDEF_STYLE_STRUCT_INHERITED

View File

@ -66,11 +66,11 @@
nsCachedStyleData::StyleStructInfo
nsCachedStyleData::gInfo[] = {
#define STYLE_STRUCT_INHERITED(name, checkdata_cb) \
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args) \
{ offsetof(nsCachedStyleData, mInheritedData), \
offsetof(nsInheritedStyleData, m##name##Data), \
PR_FALSE },
#define STYLE_STRUCT_RESET(name, checkdata_cb) \
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args) \
{ offsetof(nsCachedStyleData, mResetData), \
offsetof(nsResetStyleData, m##name##Data), \
PR_TRUE },