diff --git a/content/base/src/nsRuleNode.cpp b/content/base/src/nsRuleNode.cpp index 6c68e9ee233..063722bc61a 100644 --- a/content/base/src/nsRuleNode.cpp +++ b/content/base/src/nsRuleNode.cpp @@ -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 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 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 shell; + mPresContext->GetShell(getter_AddRefs(shell)); + nsCOMPtr set; + shell->GetStyleSet(getter_AddRefs(set)); + return set->GetDefaultStyleData()->GetStyleData(aSID); } void diff --git a/content/base/src/nsStyleSet.cpp b/content/base/src/nsStyleSet.cpp index e2a2aee206e..606c4474433 100644 --- a/content/base/src/nsStyleSet.cpp +++ b/content/base/src/nsStyleSet.cpp @@ -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 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 StyleSetImpl::ResolveStyleFor(nsIPresContext* aPresContext, nsIContent* aContent, @@ -1184,6 +1226,7 @@ StyleSetImpl::ResolveStyleFor(nsIPresContext* aPresContext, mDocRuleProcessors || mOverrideRuleProcessors) { EnsureRuleWalker(aPresContext); + NS_ENSURE_TRUE(mRuleWalker, nsnull); nsCOMPtr 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 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 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 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); } diff --git a/content/html/style/src/nsStyleUtil.cpp b/content/html/style/src/nsStyleUtil.cpp index 08ab6fcd701..4b16eee665b 100644 --- a/content/html/style/src/nsStyleUtil.cpp +++ b/content/html/style/src/nsStyleUtil.cpp @@ -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 }, diff --git a/content/shared/public/nsRuleNode.h b/content/shared/public/nsRuleNode.h index 20ef5a05826..1ffe935fef0 100644 --- a/content/shared/public/nsRuleNode.h +++ b/content/shared/public/nsRuleNode.h @@ -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); diff --git a/content/shared/public/nsStyleContext.h b/content/shared/public/nsStyleContext.h index 061237bacb9..1ff1e4c6351 100644 --- a/content/shared/public/nsStyleContext.h +++ b/content/shared/public/nsStyleContext.h @@ -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); diff --git a/content/shared/public/nsStyleStruct.h b/content/shared/public/nsStyleStruct.h index 7af7e4a4456..11111feaa75 100644 --- a/content/shared/public/nsStyleStruct.h +++ b/content/shared/public/nsStyleStruct.h @@ -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 { diff --git a/content/shared/public/nsStyleStructList.h b/content/shared/public/nsStyleStructList.h index f57734d1099..a16ab996ee2 100644 --- a/content/shared/public/nsStyleStructList.h +++ b/content/shared/public/nsStyleStructList.h @@ -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 diff --git a/content/shared/src/nsStyleStruct.cpp b/content/shared/src/nsStyleStruct.cpp index 2ab1fa3fc69..83f06dbdac1 100644 --- a/content/shared/src/nsStyleStruct.cpp +++ b/content/shared/src/nsStyleStruct.cpp @@ -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 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) && diff --git a/layout/base/public/nsIFrame.h b/layout/base/public/nsIFrame.h index 089d99b6bda..a689c25dbdd 100644 --- a/layout/base/public/nsIFrame.h +++ b/layout/base/public/nsIFrame.h @@ -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; diff --git a/layout/base/public/nsIStyleSet.h b/layout/base/public/nsIStyleSet.h index 94ebceaa910..259da145f7b 100644 --- a/layout/base/public/nsIStyleSet.h +++ b/layout/base/public/nsIStyleSet.h @@ -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 diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 089d99b6bda..a689c25dbdd 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -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; diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 6c68e9ee233..063722bc61a 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -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 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 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 shell; + mPresContext->GetShell(getter_AddRefs(shell)); + nsCOMPtr set; + shell->GetStyleSet(getter_AddRefs(set)); + return set->GetDefaultStyleData()->GetStyleData(aSID); } void diff --git a/layout/style/nsRuleNode.h b/layout/style/nsRuleNode.h index 20ef5a05826..1ffe935fef0 100644 --- a/layout/style/nsRuleNode.h +++ b/layout/style/nsRuleNode.h @@ -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); diff --git a/layout/style/nsStyleContext.h b/layout/style/nsStyleContext.h index 061237bacb9..1ff1e4c6351 100644 --- a/layout/style/nsStyleContext.h +++ b/layout/style/nsStyleContext.h @@ -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); diff --git a/layout/style/nsStyleSet.cpp b/layout/style/nsStyleSet.cpp index e2a2aee206e..606c4474433 100644 --- a/layout/style/nsStyleSet.cpp +++ b/layout/style/nsStyleSet.cpp @@ -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 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 StyleSetImpl::ResolveStyleFor(nsIPresContext* aPresContext, nsIContent* aContent, @@ -1184,6 +1226,7 @@ StyleSetImpl::ResolveStyleFor(nsIPresContext* aPresContext, mDocRuleProcessors || mOverrideRuleProcessors) { EnsureRuleWalker(aPresContext); + NS_ENSURE_TRUE(mRuleWalker, nsnull); nsCOMPtr 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 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 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 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); } diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 2ab1fa3fc69..83f06dbdac1 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -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 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) && diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 7af7e4a4456..11111feaa75 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -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 { diff --git a/layout/style/nsStyleStructList.h b/layout/style/nsStyleStructList.h index f57734d1099..a16ab996ee2 100644 --- a/layout/style/nsStyleStructList.h +++ b/layout/style/nsStyleStructList.h @@ -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 diff --git a/layout/style/nsStyleUtil.cpp b/layout/style/nsStyleUtil.cpp index 08ab6fcd701..4b16eee665b 100644 --- a/layout/style/nsStyleUtil.cpp +++ b/layout/style/nsStyleUtil.cpp @@ -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 },