From fb0a2b5caecc2d225b7f603fc750e0e524cef381 Mon Sep 17 00:00:00 2001 From: "roc+%cs.cmu.edu" Date: Tue, 8 Jan 2008 22:36:56 +0000 Subject: [PATCH] Bug 355548. Clean up MathML's font handling by moving most of it to the style system. Creates nsMathMLElement to put functionality there. Tightens MathML attribute parsing and introduces full support for 'scriptsizemultiplier', 'scriptminsize' and their interactions with CSS font-size. r+sr=dbaron git-svn-id: svn://10.0.0.236/trunk@242648 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/content/Makefile.in | 4 + mozilla/content/base/public/nsIDocument.h | 17 +- mozilla/content/base/public/nsINode.h | 4 +- mozilla/content/base/src/Makefile.in | 1 + .../content/base/src/nsAttrAndChildArray.cpp | 6 +- .../content/base/src/nsAttrAndChildArray.h | 6 +- .../base/src/nsMappedAttributeElement.cpp | 98 ++++ .../base/src/nsMappedAttributeElement.h | 84 ++++ mozilla/content/base/src/nsMappedAttributes.h | 2 +- .../events/public/nsIEventStateManager.h | 3 + .../html/content/src/nsGenericHTMLElement.cpp | 30 -- .../html/content/src/nsGenericHTMLElement.h | 16 +- .../html/document/src/nsImageDocument.cpp | 2 +- mozilla/content/mathml/Makefile.in | 47 ++ mozilla/content/mathml/content/Makefile.in | 48 ++ .../content/mathml/content/src/Makefile.in | 87 ++++ .../mathml/content/src/nsMathMLElement.cpp | 457 +++++++++++++++++ .../mathml/content/src/nsMathMLElement.h | 103 ++++ .../content/src/nsMathMLElementFactory.cpp | 55 ++ .../xml/document/src/nsXMLContentSink.cpp | 22 - mozilla/dom/src/base/nsHistory.cpp | 2 +- mozilla/dom/src/base/nsLocation.cpp | 2 +- mozilla/layout/base/nsCSSFrameConstructor.cpp | 48 ++ mozilla/layout/base/nsCSSFrameConstructor.h | 15 + mozilla/layout/base/nsPresContext.cpp | 69 +-- mozilla/layout/base/nsPresContext.h | 12 +- mozilla/layout/base/nsStyleConsts.h | 4 + mozilla/layout/build/Makefile.in | 11 +- mozilla/layout/mathml/base/src/Makefile.in | 2 + .../layout/mathml/base/src/nsIMathMLFrame.h | 78 +-- .../base/src/nsMathMLContainerFrame.cpp | 215 ++------ .../mathml/base/src/nsMathMLContainerFrame.h | 91 +--- .../base/src/nsMathMLForeignFrameWrapper.h | 10 +- .../layout/mathml/base/src/nsMathMLFrame.cpp | 350 +------------ .../layout/mathml/base/src/nsMathMLFrame.h | 35 +- .../mathml/base/src/nsMathMLmfencedFrame.cpp | 9 +- .../mathml/base/src/nsMathMLmfracFrame.cpp | 59 +-- .../mathml/base/src/nsMathMLmfracFrame.h | 7 - .../base/src/nsMathMLmmultiscriptsFrame.cpp | 9 +- .../mathml/base/src/nsMathMLmoFrame.cpp | 2 +- .../mathml/base/src/nsMathMLmoverFrame.cpp | 15 +- .../mathml/base/src/nsMathMLmoverFrame.h | 4 +- .../mathml/base/src/nsMathMLmrootFrame.cpp | 4 +- .../mathml/base/src/nsMathMLmsqrtFrame.cpp | 2 +- .../mathml/base/src/nsMathMLmstyleFrame.cpp | 39 +- .../mathml/base/src/nsMathMLmstyleFrame.h | 4 +- .../mathml/base/src/nsMathMLmsubFrame.cpp | 2 +- .../mathml/base/src/nsMathMLmsubsupFrame.cpp | 6 +- .../mathml/base/src/nsMathMLmsupFrame.cpp | 4 +- .../mathml/base/src/nsMathMLmtableFrame.cpp | 54 +- .../mathml/base/src/nsMathMLmtableFrame.h | 36 +- .../mathml/base/src/nsMathMLmunderFrame.cpp | 15 +- .../mathml/base/src/nsMathMLmunderFrame.h | 4 +- .../base/src/nsMathMLmunderoverFrame.cpp | 20 +- .../mathml/base/src/nsMathMLmunderoverFrame.h | 4 +- mozilla/layout/mathml/content/src/mathml.css | 88 +--- mozilla/layout/reftests/bugs/355548-1-ref.xml | 36 ++ mozilla/layout/reftests/bugs/355548-1.xml | 36 ++ mozilla/layout/reftests/bugs/355548-2-ref.xml | 25 + mozilla/layout/reftests/bugs/355548-2.xml | 38 ++ mozilla/layout/reftests/bugs/355548-3-ref.xml | 67 +++ mozilla/layout/reftests/bugs/355548-3.xml | 78 +++ mozilla/layout/reftests/bugs/355548-4-ref.xml | 11 + mozilla/layout/reftests/bugs/355548-4.xml | 41 ++ mozilla/layout/reftests/bugs/355548-5-ref.xml | 7 + mozilla/layout/reftests/bugs/355548-5.xml | 7 + mozilla/layout/reftests/bugs/reftest.list | 5 + mozilla/layout/style/nsCSSParser.cpp | 14 + mozilla/layout/style/nsCSSPropList.h | 8 + mozilla/layout/style/nsCSSPseudoClassList.h | 4 + mozilla/layout/style/nsCSSRuleProcessor.cpp | 8 + mozilla/layout/style/nsCSSStruct.h | 6 + mozilla/layout/style/nsRuleNode.cpp | 473 +++++++++++++----- mozilla/layout/style/nsRuleNode.h | 14 +- mozilla/layout/style/nsStyleStruct.cpp | 46 +- mozilla/layout/style/nsStyleStruct.h | 16 +- .../layout/style/test/ListCSSProperties.cpp | 5 +- 77 files changed, 2074 insertions(+), 1294 deletions(-) create mode 100644 mozilla/content/base/src/nsMappedAttributeElement.cpp create mode 100644 mozilla/content/base/src/nsMappedAttributeElement.h create mode 100644 mozilla/content/mathml/Makefile.in create mode 100644 mozilla/content/mathml/content/Makefile.in create mode 100644 mozilla/content/mathml/content/src/Makefile.in create mode 100644 mozilla/content/mathml/content/src/nsMathMLElement.cpp create mode 100644 mozilla/content/mathml/content/src/nsMathMLElement.h create mode 100644 mozilla/content/mathml/content/src/nsMathMLElementFactory.cpp create mode 100644 mozilla/layout/reftests/bugs/355548-1-ref.xml create mode 100644 mozilla/layout/reftests/bugs/355548-1.xml create mode 100644 mozilla/layout/reftests/bugs/355548-2-ref.xml create mode 100644 mozilla/layout/reftests/bugs/355548-2.xml create mode 100644 mozilla/layout/reftests/bugs/355548-3-ref.xml create mode 100644 mozilla/layout/reftests/bugs/355548-3.xml create mode 100644 mozilla/layout/reftests/bugs/355548-4-ref.xml create mode 100644 mozilla/layout/reftests/bugs/355548-4.xml create mode 100644 mozilla/layout/reftests/bugs/355548-5-ref.xml create mode 100644 mozilla/layout/reftests/bugs/355548-5.xml diff --git a/mozilla/content/Makefile.in b/mozilla/content/Makefile.in index 3189294ae6c..6e44e446f74 100644 --- a/mozilla/content/Makefile.in +++ b/mozilla/content/Makefile.in @@ -53,6 +53,10 @@ ifdef MOZ_XTF DIRS += xtf endif +ifdef MOZ_MATHML +DIRS += mathml +endif + DIRS += events ifdef ENABLE_TESTS diff --git a/mozilla/content/base/public/nsIDocument.h b/mozilla/content/base/public/nsIDocument.h index 981c1049ece..9056a617fc4 100644 --- a/mozilla/content/base/public/nsIDocument.h +++ b/mozilla/content/base/public/nsIDocument.h @@ -275,7 +275,7 @@ public: CopyASCIItoUTF16(mContentLanguage, aContentLanguage); } - // The state BidiEnabled should persist across multiple views + // The states BidiEnabled and MathMLEnabled should persist across multiple views // (screen, print) of the same document. /** @@ -297,6 +297,19 @@ public: { mBidiEnabled = aBidiEnabled; } + + /** + * Check if the document contains (or has contained) any MathML elements. + */ + PRBool GetMathMLEnabled() const + { + return mMathMLEnabled; + } + + void SetMathMLEnabled() + { + mMathMLEnabled = PR_TRUE; + } /** * Ask this document whether it's the initial document in its window. @@ -965,6 +978,8 @@ protected: // True if BIDI is enabled. PRPackedBool mBidiEnabled; + // True if a MathML element has ever been owned by this document. + PRPackedBool mMathMLEnabled; // True if this document is the initial document for a window. This should // basically be true only for documents that exist in newly-opened windows or diff --git a/mozilla/content/base/public/nsINode.h b/mozilla/content/base/public/nsINode.h index 692a68684c6..9c1fd5640ee 100644 --- a/mozilla/content/base/public/nsINode.h +++ b/mozilla/content/base/public/nsINode.h @@ -180,7 +180,9 @@ public: eDOCUMENT_FRAGMENT = 1 << 11, /** data nodes (comments, PIs, text). Nodes of this type always returns a non-null value for nsIContent::GetText() */ - eDATA_NODE = 1 << 12 + eDATA_NODE = 1 << 12, + /** nsMathMLElement */ + eMATHML = 1 << 13, }; /** diff --git a/mozilla/content/base/src/Makefile.in b/mozilla/content/base/src/Makefile.in index c4779856dd0..85013822430 100644 --- a/mozilla/content/base/src/Makefile.in +++ b/mozilla/content/base/src/Makefile.in @@ -136,6 +136,7 @@ CPPSRCS = \ nsImageLoadingContent.cpp \ nsLineBreaker.cpp \ nsLoadListenerProxy.cpp \ + nsMappedAttributeElement.cpp \ nsMappedAttributes.cpp \ nsNameSpaceManager.cpp \ nsNoDataProtocolContentPolicy.cpp \ diff --git a/mozilla/content/base/src/nsAttrAndChildArray.cpp b/mozilla/content/base/src/nsAttrAndChildArray.cpp index eec36581a61..9d1d7e27306 100644 --- a/mozilla/content/base/src/nsAttrAndChildArray.cpp +++ b/mozilla/content/base/src/nsAttrAndChildArray.cpp @@ -42,7 +42,7 @@ */ #include "nsAttrAndChildArray.h" -#include "nsGenericHTMLElement.h" +#include "nsMappedAttributeElement.h" #include "prmem.h" #include "prbit.h" #include "nsString.h" @@ -561,7 +561,7 @@ nsAttrAndChildArray::IndexOfAttr(nsIAtom* aLocalName, PRInt32 aNamespaceID) cons nsresult nsAttrAndChildArray::SetAndTakeMappedAttr(nsIAtom* aLocalName, nsAttrValue& aValue, - nsGenericHTMLElement* aContent, + nsMappedAttributeElement* aContent, nsHTMLStyleSheet* aSheet) { nsRefPtr mapped; @@ -651,7 +651,7 @@ nsAttrAndChildArray::MappedAttrCount() const } nsresult -nsAttrAndChildArray::GetModifiableMapped(nsGenericHTMLElement* aContent, +nsAttrAndChildArray::GetModifiableMapped(nsMappedAttributeElement* aContent, nsHTMLStyleSheet* aSheet, PRBool aWillAddAttr, nsMappedAttributes** aModifiable) diff --git a/mozilla/content/base/src/nsAttrAndChildArray.h b/mozilla/content/base/src/nsAttrAndChildArray.h index 5d0c1cee8ac..31fe69c049b 100644 --- a/mozilla/content/base/src/nsAttrAndChildArray.h +++ b/mozilla/content/base/src/nsAttrAndChildArray.h @@ -53,7 +53,7 @@ class nsIContent; class nsMappedAttributes; class nsHTMLStyleSheet; class nsRuleWalker; -class nsGenericHTMLElement; +class nsMappedAttributeElement; #define ATTRCHILD_ARRAY_GROWSIZE 8 #define ATTRCHILD_ARRAY_LINEAR_THRESHOLD 32 @@ -120,7 +120,7 @@ public: PRInt32 IndexOfAttr(nsIAtom* aLocalName, PRInt32 aNamespaceID = kNameSpaceID_None) const; nsresult SetAndTakeMappedAttr(nsIAtom* aLocalName, nsAttrValue& aValue, - nsGenericHTMLElement* aContent, + nsMappedAttributeElement* aContent, nsHTMLStyleSheet* aSheet); nsresult SetMappedAttrStyleSheet(nsHTMLStyleSheet* aSheet); void WalkMappedAttributeStyleRules(nsRuleWalker* aRuleWalker); @@ -134,7 +134,7 @@ private: PRUint32 NonMappedAttrCount() const; PRUint32 MappedAttrCount() const; - nsresult GetModifiableMapped(nsGenericHTMLElement* aContent, + nsresult GetModifiableMapped(nsMappedAttributeElement* aContent, nsHTMLStyleSheet* aSheet, PRBool aWillAddAttr, nsMappedAttributes** aModifiable); diff --git a/mozilla/content/base/src/nsMappedAttributeElement.cpp b/mozilla/content/base/src/nsMappedAttributeElement.cpp new file mode 100644 index 00000000000..93bc0622a24 --- /dev/null +++ b/mozilla/content/base/src/nsMappedAttributeElement.cpp @@ -0,0 +1,98 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set tw=80 expandtab softtabstop=2 ts=2 sw=2: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Mats Palmgren + * Daniel Kraft + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsMappedAttributeElement.h" +#include "nsIDocument.h" + +nsresult +nsMappedAttributeElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent, + nsIContent* aBindingParent, + PRBool aCompileEventHandlers) +{ + nsresult rv = nsMappedAttributeElementBase::BindToTree(aDocument, aParent, + aBindingParent, + aCompileEventHandlers); + NS_ENSURE_SUCCESS(rv, rv); + + if (aDocument) { + // If we're in a document now, let our mapped attrs know what their new + // sheet is. + nsHTMLStyleSheet* sheet = aDocument->GetAttributeStyleSheet(); + if (sheet) { + mAttrsAndChildren.SetMappedAttrStyleSheet(sheet); + } + } + + return rv; +} + +nsresult +nsMappedAttributeElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker) +{ + mAttrsAndChildren.WalkMappedAttributeStyleRules(aRuleWalker); + return NS_OK; +} + +PRBool +nsMappedAttributeElement::SetMappedAttribute(nsIDocument* aDocument, + nsIAtom* aName, + nsAttrValue& aValue, + nsresult* aRetval) +{ + NS_PRECONDITION(aDocument == GetCurrentDoc(), "Unexpected document"); + nsHTMLStyleSheet* sheet = aDocument ? + aDocument->GetAttributeStyleSheet() : nsnull; + + *aRetval = mAttrsAndChildren.SetAndTakeMappedAttr(aName, aValue, + this, sheet); + return PR_TRUE; +} + +nsMapRuleToAttributesFunc +nsMappedAttributeElement::GetAttributeMappingFunction() const +{ + return &MapNoAttributesInto; +} + +void +nsMappedAttributeElement::MapNoAttributesInto(const nsMappedAttributes* aAttributes, + nsRuleData* aData) +{ +} diff --git a/mozilla/content/base/src/nsMappedAttributeElement.h b/mozilla/content/base/src/nsMappedAttributeElement.h new file mode 100644 index 00000000000..be3612680bd --- /dev/null +++ b/mozilla/content/base/src/nsMappedAttributeElement.h @@ -0,0 +1,84 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set tw=80 expandtab softtabstop=2 ts=2 sw=2: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Daniel Kraft + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/** + * nsMappedAttributeElement is the base for elements supporting style mapped + * attributes via nsMappedAttributes (HTML and MathML). + */ + +#ifndef NS_MAPPEDATTRIBUTEELEMENT_H_ +#define NS_MAPPEDATTRIBUTEELEMENT_H_ + +#include "nsStyledElement.h" + +class nsMappedAttributes; +class nsRuleData; + +typedef void (*nsMapRuleToAttributesFunc)(const nsMappedAttributes* aAttributes, + nsRuleData* aData); + +typedef nsStyledElement nsMappedAttributeElementBase; + +class nsMappedAttributeElement : public nsMappedAttributeElementBase +{ + +protected: + + nsMappedAttributeElement(nsINodeInfo *aNodeInfo) + : nsMappedAttributeElementBase(aNodeInfo) + {} + +public: + virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, + nsIContent* aBindingParent, + PRBool aCompileEventHandlers); + + virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const; + + static void MapNoAttributesInto(const nsMappedAttributes* aAttributes, + nsRuleData* aRuleData); + + NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker); + virtual PRBool SetMappedAttribute(nsIDocument* aDocument, + nsIAtom* aName, + nsAttrValue& aValue, + nsresult* aRetval); +}; + +#endif // NS_MAPPEDATTRIBUTEELEMENT_H_ diff --git a/mozilla/content/base/src/nsMappedAttributes.h b/mozilla/content/base/src/nsMappedAttributes.h index 9f00c6853b0..5c86e3be38b 100644 --- a/mozilla/content/base/src/nsMappedAttributes.h +++ b/mozilla/content/base/src/nsMappedAttributes.h @@ -45,7 +45,7 @@ #define nsMappedAttributes_h___ #include "nsAttrAndChildArray.h" -#include "nsGenericHTMLElement.h" +#include "nsMappedAttributeElement.h" #include "nsIStyleRule.h" class nsIAtom; diff --git a/mozilla/content/events/public/nsIEventStateManager.h b/mozilla/content/events/public/nsIEventStateManager.h index 24afac8bf9a..e1986e5a9e6 100644 --- a/mozilla/content/events/public/nsIEventStateManager.h +++ b/mozilla/content/events/public/nsIEventStateManager.h @@ -215,5 +215,8 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIEventStateManager, NS_IEVENTSTATEMANAGER_IID) // Content is of a type that gecko can't handle #define NS_EVENT_STATE_TYPE_UNSUPPORTED \ 0x00400000 +#ifdef MOZ_MATHML +#define NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL 0x00800000 +#endif #endif // nsIEventStateManager_h__ diff --git a/mozilla/content/html/content/src/nsGenericHTMLElement.cpp b/mozilla/content/html/content/src/nsGenericHTMLElement.cpp index 696b69ba752..e2bacb4d0c2 100644 --- a/mozilla/content/html/content/src/nsGenericHTMLElement.cpp +++ b/mozilla/content/html/content/src/nsGenericHTMLElement.cpp @@ -1146,13 +1146,6 @@ nsGenericHTMLElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent, htmlDocument->ChangeContentEditableCount(this, +1); } } - - // If we're in a document now, let our mapped attrs know what their new - // sheet is. - nsHTMLStyleSheet* sheet = aDocument->GetAttributeStyleSheet(); - if (sheet) { - mAttrsAndChildren.SetMappedAttrStyleSheet(sheet); - } } return rv; @@ -1435,13 +1428,6 @@ nsGenericHTMLElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute, aNotify); } -nsresult -nsGenericHTMLElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker) -{ - mAttrsAndChildren.WalkMappedAttributeStyleRules(aRuleWalker); - return NS_OK; -} - already_AddRefed nsGenericHTMLElement::GetBaseURI() const { @@ -1540,22 +1526,6 @@ nsGenericHTMLElement::IsAttributeMapped(const nsIAtom* aAttribute) const return FindAttributeDependence(aAttribute, map, NS_ARRAY_LENGTH(map)); } -PRBool -nsGenericHTMLElement::SetMappedAttribute(nsIDocument* aDocument, - nsIAtom* aName, - nsAttrValue& aValue, - nsresult* aRetval) -{ - NS_PRECONDITION(aDocument == GetCurrentDoc(), "Unexpected document"); - nsHTMLStyleSheet* sheet = aDocument ? - aDocument->GetAttributeStyleSheet() : nsnull; - - *aRetval = mAttrsAndChildren.SetAndTakeMappedAttr(aName, aValue, - this, sheet); - return PR_TRUE; -} - - nsMapRuleToAttributesFunc nsGenericHTMLElement::GetAttributeMappingFunction() const { diff --git a/mozilla/content/html/content/src/nsGenericHTMLElement.h b/mozilla/content/html/content/src/nsGenericHTMLElement.h index 8d0cad61016..15befa464f6 100644 --- a/mozilla/content/html/content/src/nsGenericHTMLElement.h +++ b/mozilla/content/html/content/src/nsGenericHTMLElement.h @@ -38,7 +38,7 @@ #ifndef nsGenericHTMLElement_h___ #define nsGenericHTMLElement_h___ -#include "nsStyledElement.h" +#include "nsMappedAttributeElement.h" #include "nsIDOMHTMLElement.h" #include "nsINameSpaceManager.h" // for kNameSpaceID_None #include "nsIFormControl.h" @@ -50,7 +50,6 @@ class nsIDOMAttr; class nsIDOMEventListener; class nsIDOMNodeList; class nsIFrame; -class nsMappedAttributes; class nsIStyleRule; class nsChildContentList; class nsDOMCSSDeclaration; @@ -64,12 +63,8 @@ class nsILayoutHistoryState; class nsIEditor; struct nsRect; struct nsSize; -struct nsRuleData; -typedef void (*nsMapRuleToAttributesFunc)(const nsMappedAttributes* aAttributes, - nsRuleData* aData); - -typedef nsStyledElement nsGenericHTMLElementBase; +typedef nsMappedAttributeElement nsGenericHTMLElementBase; /** * A common superclass for HTML elements @@ -239,11 +234,9 @@ public: { return mAttrsAndChildren.GetAttr(aAttr); } - virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const; virtual void UpdateEditableState(); - NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker); already_AddRefed GetBaseURI() const; virtual PRBool ParseAttribute(PRInt32 aNamespaceID, @@ -252,10 +245,7 @@ public: nsAttrValue& aResult); NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const; - virtual PRBool SetMappedAttribute(nsIDocument* aDocument, - nsIAtom* aName, - nsAttrValue& aValue, - nsresult* aRetval); + virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const; /** * Get the base target for any links within this piece diff --git a/mozilla/content/html/document/src/nsImageDocument.cpp b/mozilla/content/html/document/src/nsImageDocument.cpp index daccdaee417..212195bba24 100644 --- a/mozilla/content/html/document/src/nsImageDocument.cpp +++ b/mozilla/content/html/document/src/nsImageDocument.cpp @@ -608,7 +608,7 @@ nsresult nsImageDocument::CheckOverflowing(PRBool changeState) { /* Create a scope so that the style context gets destroyed before we might - * call ClearStyleDataAndReflow. Also, holding onto pointers to the + * call RebuildStyleData. Also, holding onto pointers to the * presentatation through style resolution is potentially dangerous. */ { diff --git a/mozilla/content/mathml/Makefile.in b/mozilla/content/mathml/Makefile.in new file mode 100644 index 00000000000..71838f2e688 --- /dev/null +++ b/mozilla/content/mathml/Makefile.in @@ -0,0 +1,47 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +DIRS = content + +include $(topsrcdir)/config/rules.mk diff --git a/mozilla/content/mathml/content/Makefile.in b/mozilla/content/mathml/content/Makefile.in new file mode 100644 index 00000000000..ac483e08e95 --- /dev/null +++ b/mozilla/content/mathml/content/Makefile.in @@ -0,0 +1,48 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +DIRS = src + +include $(topsrcdir)/config/rules.mk + diff --git a/mozilla/content/mathml/content/src/Makefile.in b/mozilla/content/mathml/content/src/Makefile.in new file mode 100644 index 00000000000..9d62c66d299 --- /dev/null +++ b/mozilla/content/mathml/content/src/Makefile.in @@ -0,0 +1,87 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is Mozilla MathML DOM code. +# +# The Initial Developer of the Original Code is +# mozilla.org. +# Portions created by the Initial Developer are Copyright (C) 2007 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Vlad Sukhoy (original developer) +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = content +LIBRARY_NAME = gkcontentmathml_s +LIBXUL_LIBRARY = 1 +REQUIRES = xpcom \ + string \ + layout \ + content \ + widget \ + gfx \ + dom \ + js \ + locale \ + pref \ + webshell \ + unicharutil \ + docshell \ + thebes \ + $(NULL) + +CPPSRCS = \ + nsMathMLElement.cpp \ + nsMathMLElementFactory.cpp \ + $(NULL) + +include $(topsrcdir)/config/config.mk + +# we don't want the shared lib, but we want to force the creation of a static +# lib. +FORCE_STATIC_LIB = 1 + +EXPORTS = \ + $(NULL) + + +include $(topsrcdir)/config/rules.mk + +INCLUDES += \ + -I$(srcdir)/../../../shared/public \ + -I$(srcdir)/../../../base/src \ + $(NULL) + +DEFINES += -D_IMPL_NS_LAYOUT diff --git a/mozilla/content/mathml/content/src/nsMathMLElement.cpp b/mozilla/content/mathml/content/src/nsMathMLElement.cpp new file mode 100644 index 00000000000..3e957d67248 --- /dev/null +++ b/mozilla/content/mathml/content/src/nsMathMLElement.cpp @@ -0,0 +1,457 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is MathML DOM code. + * + * The Initial Developer of the Original Code is + * mozilla.org. + * Portions created by the Initial Developer are Copyright (C) 2007 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Vlad Sukhoy (original developer) + * Daniel Kraft (nsMathMLElement patch, attachment 262925) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsMathMLElement.h" +#include "nsDOMClassInfoID.h" // for eDOMClassInfo_MathElement_id. +#include "nsGkAtoms.h" +#include "nsCRT.h" +#include "nsRuleData.h" +#include "nsCSSValue.h" +#include "nsMappedAttributes.h" +#include "nsStyleConsts.h" +#include "nsIDocument.h" +#include "nsIEventStateManager.h" +#include "nsPresShellIterator.h" +#include "nsIPresShell.h" +#include "nsPresContext.h" +#include "nsDOMClassInfoID.h" + +//---------------------------------------------------------------------- +// nsISupports methods: + +NS_IMETHODIMP +nsMathMLElement::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + NS_PRECONDITION(aInstancePtr, "null out param"); + + nsresult rv = nsMathMLElementBase::QueryInterface(aIID, aInstancePtr); + + if (NS_SUCCEEDED(rv)) + return rv; + + nsISupports *inst = nsnull; + + if (aIID.Equals(NS_GET_IID(nsIDOMNode))) { + inst = static_cast(this); + } else if (aIID.Equals(NS_GET_IID(nsIDOMElement))) { + inst = static_cast(this); + } else if (aIID.Equals(NS_GET_IID(nsIClassInfo))) { + inst = NS_GetDOMClassInfoInstance(eDOMClassInfo_Element_id); + NS_ENSURE_TRUE(inst, NS_ERROR_OUT_OF_MEMORY); + } else { + return PostQueryInterface(aIID, aInstancePtr); + } + + NS_ADDREF(inst); + + *aInstancePtr = inst; + + return NS_OK; +} + +NS_IMPL_ADDREF_INHERITED(nsMathMLElement, nsMathMLElementBase) +NS_IMPL_RELEASE_INHERITED(nsMathMLElement, nsMathMLElementBase) + +nsresult +nsMathMLElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent, + nsIContent* aBindingParent, + PRBool aCompileEventHandlers) +{ + static const char kMathMLStyleSheetURI[] = "resource://gre/res/mathml.css"; + + nsresult rv = nsMathMLElementBase::BindToTree(aDocument, aParent, + aBindingParent, + aCompileEventHandlers); + NS_ENSURE_SUCCESS(rv, rv); + + if (aDocument && !aDocument->GetMathMLEnabled()) { + // Enable MathML and setup the style sheet during binding, not element + // construction, because we could move a MathML element from the document + // that created it to another document. + aDocument->SetMathMLEnabled(); + aDocument->EnsureCatalogStyleSheet(kMathMLStyleSheetURI); + + // Rebuild style data for all the presshells, because style system + // optimizations may have taken place assuming MathML was disabled. + // (See nsRuleNode::CheckSpecifiedProperties.) + // nsPresShellIterator skips hidden presshells, but that's OK because + // if we're changing the document for one of those presshells the whole + // presshell will be torn down. + nsPresShellIterator iter(aDocument); + nsCOMPtr shell; + while ((shell = iter.GetNextShell()) != nsnull) { + shell->GetPresContext()->PostRebuildAllStyleDataEvent(); + } + } + + return rv; +} + +PRBool +nsMathMLElement::ParseAttribute(PRInt32 aNamespaceID, + nsIAtom* aAttribute, + const nsAString& aValue, + nsAttrValue& aResult) +{ + if (aNamespaceID == kNameSpaceID_None) { + if (aAttribute == nsGkAtoms::color || + aAttribute == nsGkAtoms::mathcolor_ || + aAttribute == nsGkAtoms::background || + aAttribute == nsGkAtoms::mathbackground_) { + return aResult.ParseColor(aValue, GetOwnerDoc()); + } + } + + return nsMathMLElementBase::ParseAttribute(aNamespaceID, aAttribute, + aValue, aResult); +} + +static nsGenericElement::MappedAttributeEntry sTokenStyles[] = { + { &nsGkAtoms::mathsize_ }, + { &nsGkAtoms::fontsize_ }, + { &nsGkAtoms::mathcolor_ }, + { &nsGkAtoms::color }, + { &nsGkAtoms::mathbackground_ }, + { &nsGkAtoms::fontfamily_ }, + { nsnull } +}; + +static nsGenericElement::MappedAttributeEntry sEnvironmentStyles[] = { + { &nsGkAtoms::scriptlevel_ }, + { &nsGkAtoms::scriptminsize_ }, + { &nsGkAtoms::scriptsizemultiplier_ }, + { &nsGkAtoms::background }, + { nsnull } +}; + +PRBool +nsMathMLElement::IsAttributeMapped(const nsIAtom* aAttribute) const +{ + static const MappedAttributeEntry* const tokenMap[] = { + sTokenStyles + }; + static const MappedAttributeEntry* const mstyleMap[] = { + sTokenStyles, + sEnvironmentStyles + }; + + // We don't support mglyph (yet). + nsIAtom* tag = Tag(); + if (tag == nsGkAtoms::ms_ || tag == nsGkAtoms::mi_ || + tag == nsGkAtoms::mn_ || tag == nsGkAtoms::mo_ || + tag == nsGkAtoms::mtext_) + return FindAttributeDependence(aAttribute, tokenMap, + NS_ARRAY_LENGTH(tokenMap)); + if (tag == nsGkAtoms::mstyle_) + return FindAttributeDependence(aAttribute, mstyleMap, + NS_ARRAY_LENGTH(mstyleMap)); + return PR_FALSE; +} + +nsMapRuleToAttributesFunc +nsMathMLElement::GetAttributeMappingFunction() const +{ + // It doesn't really matter what our tag is here, because only attributes + // that satisfy IsAttributeMapped will be stored in the mapped attributes + // list and available to the mapping function + return &MapMathMLAttributesInto; +} + +// ================ +// Utilities for parsing and retrieving numeric values + +/* +The REC says: + An explicit plus sign ('+') is not allowed as part of a numeric value + except when it is specifically listed in the syntax (as a quoted '+' + or "+"), + + Units allowed + ID Description + em ems (font-relative unit traditionally used for horizontal lengths) + ex exs (font-relative unit traditionally used for vertical lengths) + px pixels, or pixel size of a "typical computer display" + in inches (1 inch = 2.54 centimeters) + cm centimeters + mm millimeters + pt points (1 point = 1/72 inch) + pc picas (1 pica = 12 points) + % percentage of default value + +Implementation here: + The numeric value is valid only if it is of the form [-] nnn.nnn + [h/v-unit] +*/ + +/* static */ PRBool +nsMathMLElement::ParseNumericValue(const nsString& aString, + nsCSSValue& aCSSValue, + PRBool aRequireLengthUnit) +{ + nsAutoString str(aString); + str.CompressWhitespace(); // aString is const in this code... + + PRInt32 stringLength = str.Length(); + if (!stringLength) + return PR_FALSE; + + nsAutoString number, unit; + + // see if the negative sign is there + PRInt32 i = 0; + PRUnichar c = str[0]; + if (c == '-') { + number.Append(c); + i++; + + // skip any space after the negative sign + if (i < stringLength && nsCRT::IsAsciiSpace(str[i])) + i++; + } + + // Gather up characters that make up the number + PRBool gotDot = PR_FALSE; + for ( ; i < stringLength; i++) { + c = str[i]; + if (gotDot && c == '.') + return PR_FALSE; // two dots encountered + else if (c == '.') + gotDot = PR_TRUE; + else if (!nsCRT::IsAsciiDigit(c)) { + str.Right(unit, stringLength - i); + // some authors leave blanks before the unit, but that shouldn't + // be allowed, so don't CompressWhitespace on 'unit'. + break; + } + number.Append(c); + } + + // Convert number to floating point + PRInt32 errorCode; + float floatValue = number.ToFloat(&errorCode); + if (NS_FAILED(errorCode)) + return PR_FALSE; + + nsCSSUnit cssUnit; + if (unit.IsEmpty()) { + if (aRequireLengthUnit) { + // We are supposed to have a length unit, but there isn't one. + // If the value is 0 we can just call it "pixels" otherwise + // this is illegal. + if (floatValue != 0.0) + return PR_FALSE; + cssUnit = eCSSUnit_Pixel; + } else { + // no explicit unit, this is a number that will act as a multiplier + cssUnit = eCSSUnit_Number; + } + } + else if (unit.EqualsLiteral("%")) { + aCSSValue.SetPercentValue(floatValue / 100.0f); + return PR_TRUE; + } + else if (unit.EqualsLiteral("em")) cssUnit = eCSSUnit_EM; + else if (unit.EqualsLiteral("ex")) cssUnit = eCSSUnit_XHeight; + else if (unit.EqualsLiteral("px")) cssUnit = eCSSUnit_Pixel; + else if (unit.EqualsLiteral("in")) cssUnit = eCSSUnit_Inch; + else if (unit.EqualsLiteral("cm")) cssUnit = eCSSUnit_Centimeter; + else if (unit.EqualsLiteral("mm")) cssUnit = eCSSUnit_Millimeter; + else if (unit.EqualsLiteral("pt")) cssUnit = eCSSUnit_Point; + else if (unit.EqualsLiteral("pc")) cssUnit = eCSSUnit_Pica; + else // unexpected unit + return PR_FALSE; + + aCSSValue.SetFloatValue(floatValue, cssUnit); + return PR_TRUE; +} + +void +nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes, + nsRuleData* aData) +{ + if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Font)) { + const nsAttrValue* value = + aAttributes->GetAttr(nsGkAtoms::scriptsizemultiplier_); + if (value && value->Type() == nsAttrValue::eString && + aData->mFontData->mScriptSizeMultiplier.GetUnit() == eCSSUnit_Null) { + nsAutoString str(value->GetStringValue()); + str.CompressWhitespace(); + // MathML numbers can't have leading '+' + if (str.Length() > 0 && str.CharAt(0) != '+') { + PRInt32 errorCode; + float floatValue = str.ToFloat(&errorCode); + // Negative scriptsizemultipliers are not parsed + if (NS_SUCCEEDED(errorCode) && floatValue >= 0.0f) { + aData->mFontData->mScriptSizeMultiplier. + SetFloatValue(floatValue, eCSSUnit_Number); + } + } + } + + value = aAttributes->GetAttr(nsGkAtoms::scriptminsize_); + if (value && value->Type() == nsAttrValue::eString && + aData->mFontData->mScriptMinSize.GetUnit() == eCSSUnit_Null) { + ParseNumericValue(value->GetStringValue(), + aData->mFontData->mScriptMinSize, PR_TRUE); + } + + value = aAttributes->GetAttr(nsGkAtoms::scriptlevel_); + if (value && value->Type() == nsAttrValue::eString && + aData->mFontData->mScriptLevel.GetUnit() == eCSSUnit_Null) { + nsAutoString str(value->GetStringValue()); + str.CompressWhitespace(); + if (str.Length() > 0) { + PRInt32 errorCode; + PRInt32 intValue = str.ToInteger(&errorCode); + if (NS_SUCCEEDED(errorCode)) { + // This is kind of cheesy ... if the scriptlevel has a sign, + // then it's a relative value and we store the nsCSSValue as an + // Integer to indicate that. Otherwise we store it as a Number + // to indicate that the scriptlevel is absolute. + PRUnichar ch = str.CharAt(0); + if (ch == '+' || ch == '-') { + aData->mFontData->mScriptLevel.SetIntValue(intValue, eCSSUnit_Integer); + } else { + aData->mFontData->mScriptLevel.SetFloatValue(intValue, eCSSUnit_Number); + } + } + } + } + + PRBool parseSizeKeywords = PR_TRUE; + value = aAttributes->GetAttr(nsGkAtoms::mathsize_); + if (!value) { + parseSizeKeywords = PR_FALSE; + value = aAttributes->GetAttr(nsGkAtoms::fontsize_); + } + if (value && value->Type() == nsAttrValue::eString && + aData->mFontData->mSize.GetUnit() == eCSSUnit_Null) { + nsAutoString str(value->GetStringValue()); + if (!ParseNumericValue(str, aData->mFontData->mSize, PR_TRUE) && + parseSizeKeywords) { + static const char sizes[3][7] = { "small", "normal", "big" }; + static const PRInt32 values[NS_ARRAY_LENGTH(sizes)] = { + NS_STYLE_FONT_SIZE_SMALL, NS_STYLE_FONT_SIZE_MEDIUM, + NS_STYLE_FONT_SIZE_LARGE + }; + str.CompressWhitespace(); + for (PRInt32 i = 0; i < NS_ARRAY_LENGTH(sizes); ++i) { + if (str.EqualsASCII(sizes[i])) { + aData->mFontData->mSize.SetIntValue(values[i], eCSSUnit_Enumerated); + break; + } + } + } + } + + value = aAttributes->GetAttr(nsGkAtoms::fontfamily_); + if (value && value->Type() == nsAttrValue::eString && + aData->mFontData->mFamily.GetUnit() == eCSSUnit_Null) { + aData->mFontData->mFamily.SetStringValue(value->GetStringValue(), + eCSSUnit_String); + aData->mFontData->mFamilyFromHTML = PR_FALSE; + } + } + + if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Background)) { + const nsAttrValue* value = + aAttributes->GetAttr(nsGkAtoms::mathbackground_); + if (!value) { + value = aAttributes->GetAttr(nsGkAtoms::background); + } + if (value && aData->mColorData->mBackColor.GetUnit() == eCSSUnit_Null) { + nscolor color; + if (value->GetColorValue(color)) { + aData->mColorData->mBackColor.SetColorValue(color); + } else { + nsAutoString str(value->GetStringValue()); + str.CompressWhitespace(); + if (str.EqualsLiteral("transparent")) { + aData->mColorData->mBackColor.SetColorValue(NS_RGBA(0,0,0,0)); + } + } + } + } + + if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Color)) { + const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::mathcolor_); + if (!value) { + value = aAttributes->GetAttr(nsGkAtoms::color); + } + nscolor color; + if (value && value->GetColorValue(color) && + aData->mColorData->mColor.GetUnit() == eCSSUnit_Null) { + aData->mColorData->mColor.SetColorValue(color); + } + } +} + +NS_IMPL_ELEMENT_CLONE(nsMathMLElement) + +PRInt32 +nsMathMLElement::IntrinsicState() const +{ + return nsMathMLElementBase::IntrinsicState() | + (mIncrementScriptLevel ? NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL : 0); +} + +PRBool +nsMathMLElement::IsNodeOfType(PRUint32 aFlags) const +{ + return !(aFlags & ~(eCONTENT | eELEMENT | eMATHML)); +} + +void +nsMathMLElement::SetIncrementScriptLevel(PRBool aIncrementScriptLevel, + PRBool aNotify) +{ + if (aIncrementScriptLevel == mIncrementScriptLevel) + return; + mIncrementScriptLevel = aIncrementScriptLevel; + + NS_ASSERTION(aNotify, "We always notify!"); + + nsIDocument* doc = GetCurrentDoc(); + if (!doc) + return; + + mozAutoDocUpdate upd(doc, UPDATE_CONTENT_STATE, PR_TRUE); + doc->ContentStatesChanged(this, nsnull, + NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL); +} diff --git a/mozilla/content/mathml/content/src/nsMathMLElement.h b/mozilla/content/mathml/content/src/nsMathMLElement.h new file mode 100644 index 00000000000..15e594be0d4 --- /dev/null +++ b/mozilla/content/mathml/content/src/nsMathMLElement.h @@ -0,0 +1,103 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is MathML DOM code. + * + * The Initial Developer of the Original Code is + * mozilla.org. + * Portions created by the Initial Developer are Copyright (C) 2007 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Vlad Sukhoy (original developer) + * Daniel Kraft (nsMathMLElement patch, attachment 262925) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsMathMLElement_h +#define nsMathMLElement_h + +#include "nsMappedAttributeElement.h" +#include "nsIDOMElement.h" + +class nsCSSValue; + +typedef nsMappedAttributeElement nsMathMLElementBase; + +/* + * The base class for MathML elements. + */ +class nsMathMLElement : public nsMathMLElementBase + , public nsIDOMElement +{ +public: + nsMathMLElement(nsINodeInfo* aNodeInfo) + : nsMathMLElementBase(aNodeInfo), mIncrementScriptLevel(PR_FALSE) + {} + + // Implementation of nsISupports is inherited from nsMathMLElementBase + NS_DECL_ISUPPORTS_INHERITED + + // Forward implementations of parent interfaces of nsMathMLElement to + // our base class + NS_FORWARD_NSIDOMNODE(nsMathMLElementBase::) + NS_FORWARD_NSIDOMELEMENT(nsMathMLElementBase::) + + nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, + nsIContent* aBindingParent, + PRBool aCompileEventHandlers); + + virtual PRBool ParseAttribute(PRInt32 aNamespaceID, + nsIAtom* aAttribute, + const nsAString& aValue, + nsAttrValue& aResult); + + NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const; + virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const; + + static PRBool ParseNumericValue(const nsString& aString, + nsCSSValue& aCSSValue, + PRBool aRequireLengthUnit); + + static void MapMathMLAttributesInto(const nsMappedAttributes* aAttributes, + nsRuleData* aRuleData); + + nsresult Clone(nsINodeInfo*, nsINode**) const; + virtual PRInt32 IntrinsicState() const; + virtual PRBool IsNodeOfType(PRUint32 aFlags) const; + + // Set during reflow as necessary. Does a style change notification, + // aNotify must be true. + void SetIncrementScriptLevel(PRBool aIncrementScriptLevel, PRBool aNotify); + PRBool GetIncrementScriptLevel() const { + return mIncrementScriptLevel; + } + +private: + PRPackedBool mIncrementScriptLevel; +}; + +#endif // nsMathMLElement_h diff --git a/mozilla/content/mathml/content/src/nsMathMLElementFactory.cpp b/mozilla/content/mathml/content/src/nsMathMLElementFactory.cpp new file mode 100644 index 00000000000..006546f5af8 --- /dev/null +++ b/mozilla/content/mathml/content/src/nsMathMLElementFactory.cpp @@ -0,0 +1,55 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is MathML DOM code. + * + * The Initial Developer of the Original Code is + * mozilla.org. + * Portions created by the Initial Developer are Copyright (C) 2007 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Vlad Sukhoy (original developer) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsContentCreatorFunctions.h" +#include "nsGkAtoms.h" +#include "nsIDocument.h" +#include "nsMathMLElement.h" + +// MathML Element Factory (declared in nsContentCreatorFunctions.h) +nsresult +NS_NewMathMLElement(nsIContent** aResult, nsINodeInfo* aNodeInfo) +{ + aNodeInfo->SetIDAttributeAtom(nsGkAtoms::id); + + nsMathMLElement* it = new (aNodeInfo) nsMathMLElement(aNodeInfo); + NS_ENSURE_TRUE(it, NS_ERROR_OUT_OF_MEMORY); + + NS_ADDREF(*aResult = it); + return NS_OK; +} diff --git a/mozilla/content/xml/document/src/nsXMLContentSink.cpp b/mozilla/content/xml/document/src/nsXMLContentSink.cpp index 817a2774895..eeaa83ded6a 100644 --- a/mozilla/content/xml/document/src/nsXMLContentSink.cpp +++ b/mozilla/content/xml/document/src/nsXMLContentSink.cpp @@ -909,28 +909,6 @@ nsXMLContentSink::MaybeStartLayout(PRBool aIgnorePendingSheets) StartLayout(aIgnorePendingSheets); } -#ifdef MOZ_MATHML -//////////////////////////////////////////////////////////////////////// -// MathML Element Factory - temporary location for bug 132844 -// Will be factored out post 1.0 - -nsresult -NS_NewMathMLElement(nsIContent** aResult, nsINodeInfo* aNodeInfo) -{ - static const char kMathMLStyleSheetURI[] = "resource://gre/res/mathml.css"; - - aNodeInfo->SetIDAttributeAtom(nsGkAtoms::id); - - // this bit of code is to load mathml.css on demand - nsIDocument *doc = aNodeInfo->GetDocument(); - if (doc) - doc->EnsureCatalogStyleSheet(kMathMLStyleSheetURI); - - return NS_NewXMLElement(aResult, aNodeInfo); -} -#endif // MOZ_MATHML - - //////////////////////////////////////////////////////////////////////// PRBool diff --git a/mozilla/dom/src/base/nsHistory.cpp b/mozilla/dom/src/base/nsHistory.cpp index 5f98bca7267..2efa1c491f3 100644 --- a/mozilla/dom/src/base/nsHistory.cpp +++ b/mozilla/dom/src/base/nsHistory.cpp @@ -295,7 +295,7 @@ nsHistory::Go() nsPresContext *pcx; if (doc && (shell = doc->GetPrimaryShell()) && (pcx = shell->GetPresContext())) { - pcx->ClearStyleDataAndReflow(); + pcx->RebuildAllStyleData(); } return NS_OK; diff --git a/mozilla/dom/src/base/nsLocation.cpp b/mozilla/dom/src/base/nsLocation.cpp index 386c7807ac8..8945b0278f9 100644 --- a/mozilla/dom/src/base/nsLocation.cpp +++ b/mozilla/dom/src/base/nsLocation.cpp @@ -892,7 +892,7 @@ nsLocation::Reload() nsPresContext *pcx; if (doc && (shell = doc->GetPrimaryShell()) && (pcx = shell->GetPresContext())) { - pcx->ClearStyleDataAndReflow(); + pcx->RebuildAllStyleData(); } return NS_OK; diff --git a/mozilla/layout/base/nsCSSFrameConstructor.cpp b/mozilla/layout/base/nsCSSFrameConstructor.cpp index cb10b00000f..15dd1bf2e0f 100644 --- a/mozilla/layout/base/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/base/nsCSSFrameConstructor.cpp @@ -1835,6 +1835,7 @@ nsCSSFrameConstructor::nsCSSFrameConstructor(nsIDocument *aDocument, , mCountersDirty(PR_FALSE) , mInitialContainingBlockIsAbsPosContainer(PR_FALSE) , mIsDestroyingFrameTree(PR_FALSE) + , mRebuildAllStyleData(PR_FALSE) { if (!gGotXBLFormPrefs) { gGotXBLFormPrefs = PR_TRUE; @@ -13263,6 +13264,39 @@ nsCSSFrameConstructor::ProcessOneRestyle(nsIContent* aContent, #define RESTYLE_ARRAY_STACKSIZE 128 +void +nsCSSFrameConstructor::RebuildAllStyleData() +{ + mRebuildAllStyleData = PR_FALSE; + + if (!mPresShell || !mPresShell->GetRootFrame()) + return; + + // Tell the style set to get the old rule tree out of the way + // so we can recalculate while maintaining rule tree immutability + nsresult rv = mPresShell->StyleSet()->BeginReconstruct(); + if (NS_FAILED(rv)) + return; + + // Recalculate all of the style contexts for the document + // Note that we can ignore the return value of ComputeStyleChangeFor + // because we never need to reframe the root frame + // XXX This could be made faster by not rerunning rule matching + // (but note that nsPresShell::SetPreferenceStyleRules currently depends + // on us re-running rule matching here + nsStyleChangeList changeList; + mPresShell->FrameManager()->ComputeStyleChangeFor(mPresShell->GetRootFrame(), + &changeList, nsChangeHint(0)); + // Process the required changes + ProcessRestyledFrames(changeList); + // Tell the style set it's safe to destroy the old rule tree. We + // must do this after the ProcessRestyledFrames call in case the + // change list has frame reconstructs in it (since frames to be + // reconstructed will still have their old style context pointers + // until they are destroyed). + mPresShell->StyleSet()->EndReconstruct(); +} + void nsCSSFrameConstructor::ProcessPendingRestyles() { @@ -13309,6 +13343,12 @@ nsCSSFrameConstructor::ProcessPendingRestyles() #ifdef DEBUG mPresShell->VerifyStyleTree(); #endif + + if (mRebuildAllStyleData) { + // We probably wasted a lot of work up above, but this seems safest + // and it should be rarely used. + RebuildAllStyleData(); + } } void @@ -13346,6 +13386,14 @@ nsCSSFrameConstructor::PostRestyleEvent(nsIContent* aContent, } } +void +nsCSSFrameConstructor::PostRebuildAllStyleDataEvent() +{ + mRebuildAllStyleData = PR_TRUE; + // Get a restyle event posted if necessary + mPresShell->ReconstructStyleDataInternal(); +} + NS_IMETHODIMP nsCSSFrameConstructor::RestyleEvent::Run() { if (!mConstructor) diff --git a/mozilla/layout/base/nsCSSFrameConstructor.h b/mozilla/layout/base/nsCSSFrameConstructor.h index fe2a28cf7a7..738e7b4d2a3 100644 --- a/mozilla/layout/base/nsCSSFrameConstructor.h +++ b/mozilla/layout/base/nsCSSFrameConstructor.h @@ -177,10 +177,24 @@ public: // If the caller wants that to happen synchronously, it needs to handle that // itself. void ProcessPendingRestyles(); + + void RebuildAllStyleData(); void PostRestyleEvent(nsIContent* aContent, nsReStyleHint aRestyleHint, nsChangeHint aMinChangeHint); + /** + * Asynchronously clear style data from the root frame downwards and ensure + * it will all be rebuilt. This is safe to call anytime; it will schedule + * a restyle and take effect next time style changes are flushed. + * This method is used to recompute the style data when some change happens + * outside of any style rules, like a color preference change or a change + * in a system font size, or to fix things up when an optimization in the + * style data has become invalid. We assume that the root frame will not + * need to be reframed. + */ + void PostRebuildAllStyleDataEvent(); + // Request to create a continuing frame nsresult CreateContinuingFrame(nsPresContext* aPresContext, nsIFrame* aFrame, @@ -1134,6 +1148,7 @@ private: PRPackedBool mCountersDirty : 1; PRPackedBool mInitialContainingBlockIsAbsPosContainer : 1; PRPackedBool mIsDestroyingFrameTree : 1; + PRPackedBool mRebuildAllStyleData : 1; nsRevocableEventPtr mRestyleEvent; diff --git a/mozilla/layout/base/nsPresContext.cpp b/mozilla/layout/base/nsPresContext.cpp index 58807b4de68..b314960b01b 100644 --- a/mozilla/layout/base/nsPresContext.cpp +++ b/mozilla/layout/base/nsPresContext.cpp @@ -701,38 +701,6 @@ nsPresContext::GetUserPreferences() SetBidi(bidiOptions, PR_FALSE); } -void -nsPresContext::ClearStyleDataAndReflow() -{ - // This method is used to recompute the style data when some change happens - // outside of any style rules, like a color preference change or a change - // in a system font size - if (mShell && mShell->GetRootFrame()) { - // Tell the style set to get the old rule tree out of the way - // so we can recalculate while maintaining rule tree immutability - nsresult rv = mShell->StyleSet()->BeginReconstruct(); - if (NS_FAILED(rv)) - return; - // Recalculate all of the style contexts for the document - // Note that we can ignore the return value of ComputeStyleChangeFor - // because we never need to reframe the root frame - // XXX This could be made faster by not rerunning rule matching - // (but note that nsPresShell::SetPreferenceStyleRules currently depends - // on us re-running rule matching here - nsStyleChangeList changeList; - mShell->FrameManager()->ComputeStyleChangeFor(mShell->GetRootFrame(), - &changeList, nsChangeHint(0)); - // Tell the frame constructor to process the required changes - mShell->FrameConstructor()->ProcessRestyledFrames(changeList); - // Tell the style set it's safe to destroy the old rule tree. We - // must do this after the ProcessRestyledFrames call in case the - // change list has frame reconstructs in it (since frames to be - // reconstructed will still have their old style context pointers - // until they are destroyed). - mShell->StyleSet()->EndReconstruct(); - } -} - static const char sMinFontSizePref[] = "browser.display.auto_quality_min_font_size"; void @@ -755,13 +723,13 @@ nsPresContext::PreferenceChanged(const char* aPrefName) nscoord height = NSToCoordRound(oldHeightDevPixels*AppUnitsPerDevPixel()); vm->SetWindowDimensions(width, height); - ClearStyleDataAndReflow(); + RebuildAllStyleData(); } return; } if (!nsCRT::strcmp(aPrefName, sMinFontSizePref)) { mAutoQualityMinFontSizePixelsPref = nsContentUtils::GetIntPref(sMinFontSizePref); - ClearStyleDataAndReflow(); + RebuildAllStyleData(); return; } // we use a zero-delay timer to coalesce multiple pref updates @@ -796,7 +764,7 @@ nsPresContext::UpdateAfterPreferencesChanged() } mDeviceContext->FlushFontCache(); - ClearStyleDataAndReflow(); + RebuildAllStyleData(); } nsresult @@ -982,8 +950,7 @@ nsPresContext::Observe(nsISupports* aSubject, if (!nsCRT::strcmp(aTopic, "charset")) { UpdateCharSet(NS_LossyConvertUTF16toASCII(aData)); mDeviceContext->FlushFontCache(); - ClearStyleDataAndReflow(); - + RebuildAllStyleData(); return NS_OK; } @@ -1174,7 +1141,7 @@ nsPresContext::SetFullZoom(float aZoom) mFullZoom = aZoom; GetViewManager()->SetWindowDimensions(NSToCoordRound(oldWidthDevPixels*AppUnitsPerDevPixel()), NSToCoordRound(oldHeightDevPixels*AppUnitsPerDevPixel())); - ClearStyleDataAndReflow(); + RebuildAllStyleData(); mCurAppUnitsPerDevPixel = AppUnitsPerDevPixel(); } @@ -1284,14 +1251,14 @@ nsPresContext::GetBidiUtils() } void -nsPresContext::SetBidi(PRUint32 aSource, PRBool aForceReflow) +nsPresContext::SetBidi(PRUint32 aSource, PRBool aForceRestyle) { // Don't do all this stuff unless the options have changed. if (aSource == GetBidi()) { return; } - NS_ASSERTION(!(aForceReflow && (GetBidi() == 0)), + NS_ASSERTION(!(aForceRestyle && (GetBidi() == 0)), "ForceReflow on new prescontext"); Document()->SetBidiOptions(aSource); @@ -1311,8 +1278,8 @@ nsPresContext::SetBidi(PRUint32 aSource, PRBool aForceReflow) SetVisualMode(IsVisualCharset(doc->GetDocumentCharacterSet())); } } - if (aForceReflow) { - ClearStyleDataAndReflow(); + if (aForceRestyle) { + RebuildAllStyleData(); } } @@ -1373,7 +1340,7 @@ nsPresContext::ThemeChangedInternal() // immutability has been violated since any style rule that uses // system colors or fonts (and probably -moz-appearance as well) has // changed. - nsPresContext::ClearStyleDataAndReflow(); + RebuildAllStyleData(); } void @@ -1409,7 +1376,21 @@ nsPresContext::SysColorChangedInternal() // data without reflowing/updating views will lead to incorrect change hints // later, because when generating change hints, any style structs which have // been cleared and not reread are assumed to not be used at all. - ClearStyleDataAndReflow(); + // XXXroc not sure what to make of the above comment, because we don't reflow + // synchronously here + RebuildAllStyleData(); +} + +void +nsPresContext::RebuildAllStyleData() +{ + mShell->FrameConstructor()->RebuildAllStyleData(); +} + +void +nsPresContext::PostRebuildAllStyleDataEvent() +{ + mShell->FrameConstructor()->PostRebuildAllStyleDataEvent(); } void diff --git a/mozilla/layout/base/nsPresContext.h b/mozilla/layout/base/nsPresContext.h index a5e5ffad0bb..cffdb6b5151 100644 --- a/mozilla/layout/base/nsPresContext.h +++ b/mozilla/layout/base/nsPresContext.h @@ -201,6 +201,9 @@ public: { return GetPresShell()->FrameManager(); } #endif + void RebuildAllStyleData(); + void PostRebuildAllStyleDataEvent(); + /** * Access compatibility mode for this context. This is the same as * our document's compatibility mode. @@ -238,11 +241,6 @@ public: */ nsIAtom* Medium() { return mMedium; } - /** - * Clear style data from the root frame downwards, and reflow. - */ - NS_HIDDEN_(void) ClearStyleDataAndReflow(); - void* AllocateFromShell(size_t aSize) { if (mShell) @@ -468,7 +466,7 @@ public: float TextZoom() { return mTextZoom; } void SetTextZoom(float aZoom) { mTextZoom = aZoom; - ClearStyleDataAndReflow(); + RebuildAllStyleData(); } float GetFullZoom() { return mFullZoom; } @@ -637,7 +635,7 @@ public: * Set the Bidi options for the presentation context */ NS_HIDDEN_(void) SetBidi(PRUint32 aBidiOptions, - PRBool aForceReflow = PR_FALSE); + PRBool aForceRestyle = PR_FALSE); /** * Get the Bidi options for the presentation context diff --git a/mozilla/layout/base/nsStyleConsts.h b/mozilla/layout/base/nsStyleConsts.h index 99847cd771e..f7d0f6ae6a0 100644 --- a/mozilla/layout/base/nsStyleConsts.h +++ b/mozilla/layout/base/nsStyleConsts.h @@ -428,6 +428,10 @@ #define NS_STYLE_FONT_LIST 15 #define NS_STYLE_FONT_FIELD 16 +// defaults per MathML spec +#define NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER 0.71f +#define NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT 8 + // See nsStylePosition::mWidth, mMinWidth, mMaxWidth #define NS_STYLE_WIDTH_MAX_CONTENT 0 #define NS_STYLE_WIDTH_MIN_CONTENT 1 diff --git a/mozilla/layout/build/Makefile.in b/mozilla/layout/build/Makefile.in index 32184a3be0d..fecad7d6d72 100644 --- a/mozilla/layout/build/Makefile.in +++ b/mozilla/layout/build/Makefile.in @@ -178,9 +178,10 @@ endif ifdef MOZ_MATHML SHARED_LIBRARY_LIBS += \ - ../mathml/content/src/$(LIB_PREFIX)gkmathmlcon_s.$(LIB_SUFFIX) \ - ../mathml/base/src/$(LIB_PREFIX)gkmathmlbase_s.$(LIB_SUFFIX) \ - $(NULL) + ../mathml/content/src/$(LIB_PREFIX)gkmathmlcon_s.$(LIB_SUFFIX) \ + ../mathml/base/src/$(LIB_PREFIX)gkmathmlbase_s.$(LIB_SUFFIX) \ + $(DEPTH)/content/mathml/content/src/$(LIB_PREFIX)gkcontentmathml_s.$(LIB_SUFFIX) \ + $(NULL) endif ifdef MOZ_XTF @@ -191,10 +192,10 @@ endif ifdef MOZ_SVG SHARED_LIBRARY_LIBS += \ - ../svg/base/src/$(LIB_PREFIX)gksvgbase_s.$(LIB_SUFFIX) \ + ../svg/base/src/$(LIB_PREFIX)gksvgbase_s.$(LIB_SUFFIX) \ $(DEPTH)/content/svg/document/src/$(LIB_PREFIX)gkconsvgdoc_s.$(LIB_SUFFIX) \ $(DEPTH)/content/svg/content/src/$(LIB_PREFIX)gkcontentsvg_s.$(LIB_SUFFIX) \ - $(NULL) + $(NULL) endif ifdef MOZ_PLAINTEXT_EDITOR_ONLY diff --git a/mozilla/layout/mathml/base/src/Makefile.in b/mozilla/layout/mathml/base/src/Makefile.in index b3fb2d09971..a09504b9a4b 100644 --- a/mozilla/layout/mathml/base/src/Makefile.in +++ b/mozilla/layout/mathml/base/src/Makefile.in @@ -76,6 +76,8 @@ LOCAL_INCLUDES = \ -I$(srcdir)/../../../generic \ -I$(srcdir)/../../../tables \ -I$(srcdir)/../../content/src \ + -I$(topsrcdir)/content/base/src \ + -I$(topsrcdir)/content/mathml/content/src \ -I$(srcdir)/../../../xul/base/src \ $(NULL) diff --git a/mozilla/layout/mathml/base/src/nsIMathMLFrame.h b/mozilla/layout/mathml/base/src/nsIMathMLFrame.h index 7ebdfb25163..e758c8bbd90 100644 --- a/mozilla/layout/mathml/base/src/nsIMathMLFrame.h +++ b/mozilla/layout/mathml/base/src/nsIMathMLFrame.h @@ -226,19 +226,15 @@ public: TransmitAutomaticData() = 0; /* UpdatePresentationData : - * Increments the scriptlevel of the frame, and updates its displaystyle and - * compression flags. The displaystyle flag of an environment gets updated - * according to the MathML specification. A frame becomes "compressed" (or - * "cramped") according to TeX rendering rules (TeXBook, Ch.17, p.140-141). + * Updates the frame's displaystyle and compression flags. The displaystyle + * flag of an environment gets updated according to the MathML specification. + * A frame becomes "compressed" (or "cramped") according to TeX rendering + * rules (TeXBook, Ch.17, p.140-141). * * Note that is the only tag which allows to set - * - * to reset or increment the scriptlevel in a manual way. + * * Therefore has its own peculiar version of this method. * - * @param aScriptLevelIncrement [in] - * The value with which to increment mScriptLevel in the frame. - * * @param aFlagsValues [in] * The new values (e.g., display, compress) that are going to be * updated. @@ -255,20 +251,17 @@ public: * update some flags in the frame, leaving the other flags unchanged. */ NS_IMETHOD - UpdatePresentationData(PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, + UpdatePresentationData(PRUint32 aFlagsValues, PRUint32 aWhichFlags) = 0; /* UpdatePresentationDataFromChildAt : - * Increments the scriplevel and sets the displaystyle and compression flags - * on the whole tree. For child frames at aFirstIndex up to aLastIndex, this - * method sets their displaystyle and compression flags, and increment their - * mScriptLevel with aScriptLevelIncrement. The update is propagated down - * the subtrees of each of these child frames. + * Sets displaystyle and compression flags on the whole tree. For child frames + * at aFirstIndex up to aLastIndex, this method sets their displaystyle and + * compression flags. The update is propagated down the subtrees of each of + * these child frames. * * Note that is the only tag which allows - * - * to reset or increment the scriptlevel in a manual way. + * * Therefore has its own peculiar version of this method. * * @param aFirstIndex [in] @@ -278,9 +271,6 @@ public: * Index of the last child where to stop the update. * A value of -1 means up to last existing child. * - * @param aScriptLevelIncrement [in] - * The value with which to increment mScriptLevel in the whole sub-trees. - * * @param aFlagsValues [in] * The new values (e.g., display, compress) that are going to be * assigned in the whole sub-trees. @@ -292,40 +282,8 @@ public: NS_IMETHOD UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, PRInt32 aLastIndex, - PRInt32 aScriptLevelIncrement, PRUint32 aFlagsValues, PRUint32 aWhichFlags) = 0; - - /* ReResolveScriptStyle : - * During frame construction, the Style System gives us style contexts in - * which the sizes of the fonts are not suitable for scripting elements. - * Our expected behavior is that, when given the markup base arguments, - * we want to render the 'base' in a normal size, and the 'arguments' in a smaller - * size. This is a common functionality to tags like msub, msup, msubsup, mover, - * munder, munderover, mmultiscripts. Moreover, we want the reduction of the font - * size to happen in a top-down manner within the hierarchies of sub-expressions; - * and more importantly, we don't want the sizes to keep decreasing up to a point - * where the scripts become unreadably small. - * - * In general, this scaling effet arises when the scriptlevel changes between a - * parent and a child. Whenever the scriptlevel changes, either automatically or - * by being explicitly incremented, decremented, or set, the current font size has - * to be multiplied by the predefined value of 'scriptsizemultiplier' to the power - * of the change in the scriptlevel, and this scaling effect (downwards or upwards) - * has to be propagated down the subtrees, with the caveat that the font size is - * never allowed to go below the predefined value of 'scriptminsize' within a - * sub-expression. - * - * ReResolveScriptStyle() will walk a subtree to cause this mathml-specific behavior - * to happen. The method is recursive and only a top-level parent wishing to reflect - * the changes in its children needs to call to the method. - * - * This function is *very* expensive. Unfortunately, there isn't much - * to do about it at the moment. For background on the problem @see - * http://groups.google.com/groups?selm=3A9192B5.D22B6C38%40maths.uq.edu.au - */ - NS_IMETHOD - ReResolveScriptStyle(PRInt32 aParentScriptLevel) = 0; }; // struct used by a container frame to keep track of its embellishments. @@ -379,15 +337,10 @@ struct nsPresentationData { // up-pointer on the mstyle frame, if any, that defines the scope nsIFrame* mstyle; - // level of nested frames within: msub, msup, msubsup, munder, - // mover, munderover, mmultiscripts, mfrac, mroot, mtable. - PRInt32 scriptLevel; - nsPresentationData() { flags = 0; baseFrame = nsnull; mstyle = nsnull; - scriptLevel = 0; } }; @@ -422,12 +375,6 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIMathMLFrame, NS_IMATHMLFRAME_IID) // horizontal stretch command on all their non-empty children #define NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY 0x00000008 -// This bit is set if the frame has the explicit attribute -// scriptlevel="value". It is only relevant to because that's -// the only tag where the attribute is allowed by the spec. -// Note: the flag is not set if the instead has an incremental +/-value. -#define NS_MATHML_EXPLICIT_SCRIPTLEVEL 0x00000010 - // This bit is set if the frame has the explicit attribute // displaystyle="true" or "false". It is only relevant to and // because they are the only tags where the attribute is allowed by the spec. @@ -464,9 +411,6 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIMathMLFrame, NS_IMATHMLFRAME_IID) #define NS_MATHML_HAS_EXPLICIT_DISPLAYSTYLE(_flags) \ (NS_MATHML_EXPLICIT_DISPLAYSTYLE == ((_flags) & NS_MATHML_EXPLICIT_DISPLAYSTYLE)) -#define NS_MATHML_HAS_EXPLICIT_SCRIPTLEVEL(_flags) \ - (NS_MATHML_EXPLICIT_SCRIPTLEVEL == ((_flags) & NS_MATHML_EXPLICIT_SCRIPTLEVEL)) - #define NS_MATHML_HAS_ERROR(_flags) \ (NS_MATHML_ERROR == ((_flags) & NS_MATHML_ERROR)) diff --git a/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.cpp index 358e001b5da..de0fbfbfd7b 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.cpp @@ -64,6 +64,7 @@ #include "nsStyleSet.h" #include "nsDisplayList.h" #include "nsCSSFrameConstructor.h" +#include "nsIReflowCallback.h" NS_DEFINE_CID(kInlineFrameCID, NS_INLINE_FRAME_CID); @@ -569,29 +570,28 @@ nsMathMLContainerFrame::FinalizeReflow(nsIRenderingContext& aRenderingContext, // a subtree that may contain non-mathml container frames /* static */ void nsMathMLContainerFrame::PropagatePresentationDataFor(nsIFrame* aFrame, - PRInt32 aScriptLevelIncrement, PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate) { - if (!aFrame || (!aFlagsToUpdate && !aScriptLevelIncrement)) + if (!aFrame || !aFlagsToUpdate) return; nsIMathMLFrame* mathMLFrame; aFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); if (mathMLFrame) { // update - mathMLFrame->UpdatePresentationData(aScriptLevelIncrement, aFlagsValues, + mathMLFrame->UpdatePresentationData(aFlagsValues, aFlagsToUpdate); // propagate using the base method to make sure that the control // is passed on to MathML frames that may be overloading the method mathMLFrame->UpdatePresentationDataFromChildAt(0, -1, - aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); + aFlagsValues, aFlagsToUpdate); } else { // propagate down the subtrees nsIFrame* childFrame = aFrame->GetFirstChild(nsnull); while (childFrame) { PropagatePresentationDataFor(childFrame, - aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); + aFlagsValues, aFlagsToUpdate); childFrame = childFrame->GetNextSibling(); } } @@ -601,11 +601,10 @@ nsMathMLContainerFrame::PropagatePresentationDataFor(nsIFrame* aFrame, nsMathMLContainerFrame::PropagatePresentationDataFromChildAt(nsIFrame* aParentFrame, PRInt32 aFirstChildIndex, PRInt32 aLastChildIndex, - PRInt32 aScriptLevelIncrement, PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate) { - if (!aParentFrame || (!aFlagsToUpdate && !aScriptLevelIncrement)) + if (!aParentFrame || !aFlagsToUpdate) return; PRInt32 index = 0; nsIFrame* childFrame = aParentFrame->GetFirstChild(nsnull); @@ -614,131 +613,13 @@ nsMathMLContainerFrame::PropagatePresentationDataFromChildAt(nsIFrame* aPa ((aLastChildIndex <= 0) || ((aLastChildIndex > 0) && (index <= aLastChildIndex)))) { PropagatePresentationDataFor(childFrame, - aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); + aFlagsValues, aFlagsToUpdate); } index++; childFrame = childFrame->GetNextSibling(); } } -// helper to let the scriptstyle re-resolution pass through -// a subtree that may contain non-mathml container frames. -// This function is *very* expensive. Unfortunately, there isn't much -// to do about it at the moment. For background on the problem @see -// http://groups.google.com/groups?selm=3A9192B5.D22B6C38%40maths.uq.edu.au -/* static */ void -nsMathMLContainerFrame::PropagateScriptStyleFor(nsIFrame* aFrame, - PRInt32 aParentScriptLevel) -{ - if (!aFrame) - return; - nsIMathMLFrame* mathMLFrame; - aFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); - if (mathMLFrame) { - // we will re-resolve our style data based on our current scriptlevel - nsPresentationData presentationData; - mathMLFrame->GetPresentationData(presentationData); - PRInt32 gap = presentationData.scriptLevel - aParentScriptLevel; - - // since we are a MathML frame, our current scriptlevel becomes - // the one to use when we will propagate the recursion - aParentScriptLevel = presentationData.scriptLevel; - - nsStyleContext* oldStyleContext = aFrame->GetStyleContext(); - nsStyleContext* parentContext = oldStyleContext->GetParent(); - - nsIContent* content = aFrame->GetContent(); - if (!gap) { - // unset any -moz-math-font-size attribute without notifying that we want a reflow - // (but leave it to the primary frame to do that, a child pseudo can't overrule) - if (!aFrame->GetParent() || aFrame->GetParent()->GetContent() != content) - content->UnsetAttr(kNameSpaceID_None, nsGkAtoms::MOZfontsize, PR_FALSE); - } - else { - // By default scriptminsize=8pt and scriptsizemultiplier=0.71 - nscoord scriptminsize = aFrame->PresContext()->PointsToAppUnits(NS_MATHML_SCRIPTMINSIZE); - float scriptsizemultiplier = NS_MATHML_SCRIPTSIZEMULTIPLIER; -#if 0 - // XXX Bug 44201 - // user-supplied scriptminsize and scriptsizemultiplier that are - // restricted to particular elements are not supported because our - // css rules are fixed in mathml.css and are applicable to all elements. - - // see if there is a scriptminsize attribute on a that wraps us - GetAttribute(nsnull, presentationData.mstyle, - nsGkAtoms::scriptminsize_, fontsize); - if (!fontsize.IsEmpty()) { - nsCSSValue cssValue; - if (ParseNumericValue(fontsize, cssValue)) { - nsCSSUnit unit = cssValue.GetUnit(); - if (eCSSUnit_Number == unit) - scriptminsize = nscoord(float(scriptminsize) * cssValue.GetFloatValue()); - else if (eCSSUnit_Percent == unit) - scriptminsize = nscoord(float(scriptminsize) * cssValue.GetPercentValue()); - else if (eCSSUnit_Null != unit) - scriptminsize = CalcLength(mStyleContext, cssValue); - } - } -#endif - - // figure out the incremental factor - nsAutoString fontsize; - if (0 > gap) { // the size is going to be increased - if (gap < NS_MATHML_CSS_NEGATIVE_SCRIPTLEVEL_LIMIT) - gap = NS_MATHML_CSS_NEGATIVE_SCRIPTLEVEL_LIMIT; - gap = -gap; - scriptsizemultiplier = 1.0f / scriptsizemultiplier; - fontsize.AssignLiteral("-"); - } - else { // the size is going to be decreased - if (gap > NS_MATHML_CSS_POSITIVE_SCRIPTLEVEL_LIMIT) - gap = NS_MATHML_CSS_POSITIVE_SCRIPTLEVEL_LIMIT; - fontsize.AssignLiteral("+"); - } - fontsize.AppendInt(gap, 10); - // we want to make sure that the size will stay readable - const nsStyleFont* font = parentContext->GetStyleFont(); - nscoord newFontSize = font->mFont.size; - while (0 < gap--) { - newFontSize = (nscoord)((float)(newFontSize) * scriptsizemultiplier); - } - if (newFontSize <= scriptminsize) { - fontsize.AssignLiteral("scriptminsize"); - } - - // set the -moz-math-font-size attribute without notifying that we want a reflow - content->SetAttr(kNameSpaceID_None, nsGkAtoms::MOZfontsize, - fontsize, PR_FALSE); - } - - // now, re-resolve the style contexts in our subtree - nsFrameManager *fm = aFrame->PresContext()->FrameManager(); - nsStyleChangeList changeList; - fm->ComputeStyleChangeFor(aFrame, &changeList, NS_STYLE_HINT_NONE); -#ifdef DEBUG - // Use the parent frame to make sure we catch in-flows and such - nsIFrame* parentFrame = aFrame->GetParent(); - fm->DebugVerifyStyleTree(parentFrame ? parentFrame : aFrame); -#endif - } - - // recurse down the subtrees for changes that may arise deep down - nsIFrame* childFrame = aFrame->GetFirstChild(nsnull); - while (childFrame) { - childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); - if (mathMLFrame) { - // propagate using the base method to make sure that the control - // is passed on to MathML frames that may be overloading the method - mathMLFrame->ReResolveScriptStyle(aParentScriptLevel); - } - else { - PropagateScriptStyleFor(childFrame, aParentScriptLevel); - } - childFrame = childFrame->GetNextSibling(); - } -} - - /* ////////////////// * Frame construction * ============================================================================= @@ -776,22 +657,6 @@ nsMathMLContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, return rv; } -// This method is called in a top-down manner, as we descend the frame tree -// during its construction -NS_IMETHODIMP -nsMathMLContainerFrame::Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) -{ - MapCommonAttributesIntoCSS(PresContext(), aContent); - - // let the base class do its Init() - return nsHTMLContainerFrame::Init(aContent, aParent, aPrevInFlow); - - // ...We will build our automatic MathML data once the entire ... - // tree is constructed. -} - // Note that this method re-builds the automatic data in the children -- not // in aParentFrame itself (except for those particular operations that the // parent frame may do in its TransmitAutomaticData()). @@ -827,7 +692,6 @@ nsMathMLContainerFrame::ReLayoutChildren(nsIFrame* aParentFrame, return NS_OK; // walk-up to the first frame that is a MathML frame, stop if we reach - PRInt32 parentScriptLevel = 0; nsIFrame* frame = aParentFrame; while (1) { nsIFrame* parent = frame->GetParent(); @@ -837,12 +701,8 @@ nsMathMLContainerFrame::ReLayoutChildren(nsIFrame* aParentFrame, // stop if it is a MathML frame nsIMathMLFrame* mathMLFrame; frame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); - if (mathMLFrame) { - nsPresentationData parentData; - mathMLFrame->GetPresentationData(parentData); - parentScriptLevel = parentData.scriptLevel; + if (mathMLFrame) break; - } // stop if we reach the root tag nsIContent* content = frame->GetContent(); @@ -863,22 +723,6 @@ nsMathMLContainerFrame::ReLayoutChildren(nsIFrame* aParentFrame, // re-sync the presentation data and embellishment data of our children RebuildAutomaticDataForChildren(frame); - // re-resolve the style data to sync any change of script sizes - nsIFrame* childFrame = aParentFrame->GetFirstChild(nsnull); - while (childFrame) { - nsIMathMLFrame* mathMLFrame; - childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); - if (mathMLFrame) { - // propagate using the base method to make sure that the control - // is passed on to MathML frames that may be overloading the method - mathMLFrame->ReResolveScriptStyle(parentScriptLevel); - } - else { - PropagateScriptStyleFor(childFrame, parentScriptLevel); - } - childFrame = childFrame->GetNextSibling(); - } - // Ask our parent frame to reflow us nsIFrame* parent = frame->GetParent(); NS_ASSERTION(parent, "No parent to pass the reflow request up to"); @@ -963,10 +807,6 @@ nsMathMLContainerFrame::AttributeChanged(PRInt32 aNameSpaceID, nsIAtom* aAttribute, PRInt32 aModType) { - // Attributes common to MathML tags - if (CommonAttributeChangedFor(PresContext(), mContent, aAttribute)) - return NS_OK; - // XXX Since they are numerous MathML attributes that affect layout, and // we can't check all of them here, play safe by requesting a reflow. // XXXldb This should only do work for attributes that cause changes! @@ -1303,11 +1143,12 @@ public: InitMetricsForChild(); // add inter frame spacing + const nsStyleFont* font = mParentFrame->GetStyleFont(); nscoord space = - GetInterFrameSpacing(mParentFrame->mPresentationData.scriptLevel, + GetInterFrameSpacing(font->mScriptLevel, prevFrameType, mChildFrameType, &mFromFrameType, &mCarrySpace); - mX += space * GetThinSpace(mParentFrame->GetStyleFont()); + mX += space * GetThinSpace(font); return *this; } @@ -1402,6 +1243,38 @@ nsMathMLContainerFrame::PositionRowChildFrames(nscoord aOffsetX, } } +class ForceReflow : public nsIReflowCallback { +public: + virtual PRBool ReflowFinished() { + return PR_TRUE; + } + virtual void ReflowCallbackCanceled() {} +}; + +// We only need one of these so we just make it a static global, no need +// to dynamically allocate/destroy it. +static ForceReflow gForceReflow; + +void +nsMathMLContainerFrame::SetIncrementScriptLevel(PRInt32 aChildIndex, PRBool aIncrement) +{ + nsIFrame* child = nsFrameList(GetFirstChild(nsnull)).FrameAt(aChildIndex); + if (!child) + return; + nsIContent* content = child->GetContent(); + if (!content->IsNodeOfType(nsINode::eMATHML)) + return; + nsMathMLElement* element = static_cast(content); + + if (element->GetIncrementScriptLevel() == aIncrement) + return; + + // XXXroc this does a ContentStatesChanged, is it safe to call here? If + // not we should do it in a post-reflow callback. + element->SetIncrementScriptLevel(aIncrement, PR_TRUE); + PresContext()->PresShell()->PostReflowCallback(&gForceReflow); +} + // helpers to fix the inter-spacing when is the only parent // e.g., it fixes f q f I @@ -1450,7 +1323,7 @@ nsMathMLContainerFrame::FixInterFrameSpacing(nsHTMLReflowMetrics& aDesiredSize) nsIAtom *parentTag = parentContent->Tag(); if (parentTag == nsGkAtoms::math || parentTag == nsGkAtoms::mtd_) { - gap = GetInterFrameSpacingFor(mPresentationData.scriptLevel, mParent, this); + gap = GetInterFrameSpacingFor(GetStyleFont()->mScriptLevel, mParent, this); // add our own italic correction nscoord leftCorrection = 0, italicCorrection = 0; GetItalicCorrection(mBoundingMetrics, leftCorrection, italicCorrection); diff --git a/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.h b/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.h index 49dcc6ebe2d..ce256264bd5 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.h +++ b/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.h @@ -61,16 +61,6 @@ * to position children in various customized ways. */ -// Parameters to handle the change of font-size induced by changing the -// scriptlevel. These are hard-coded values that match with the rules in -// mathml.css. Note that mScriptLevel can exceed these bounds, but the -// scaling effect on the font-size will be bounded. The following bounds can -// be expanded provided the new corresponding rules are added in mathml.css. -#define NS_MATHML_CSS_POSITIVE_SCRIPTLEVEL_LIMIT +5 -#define NS_MATHML_CSS_NEGATIVE_SCRIPTLEVEL_LIMIT -5 -#define NS_MATHML_SCRIPTSIZEMULTIPLIER 0.71f -#define NS_MATHML_SCRIPTMINSIZE 8 - // Options for the preferred size at which to stretch our stretchy children #define STRETCH_CONSIDER_ACTUAL_SIZE 0x00000001 // just use our current size #define STRETCH_CONSIDER_EMBELLISHMENTS 0x00000002 // size calculations include embellishments @@ -100,21 +90,25 @@ public: NS_IMETHOD UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, PRInt32 aLastIndex, - PRInt32 aScriptLevelIncrement, PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate) { PropagatePresentationDataFromChildAt(this, aFirstIndex, aLastIndex, - aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); - return NS_OK; - } - - NS_IMETHOD - ReResolveScriptStyle(PRInt32 aParentScriptLevel) - { - PropagateScriptStyleFor(this, aParentScriptLevel); + aFlagsValues, aFlagsToUpdate); return NS_OK; } + + // helper to set the "increment script level" flag on the element belonging + // to a child frame given by aChildIndex. + // When this flag is set, the style system will increment the scriptlevel + // for the child element. This is needed for situations where the style system + // cannot itself determine the scriptlevel (mfrac, munder, mover, munderover). + // This should be called during reflow. We set the flag and if it changed, + // we request appropriate restyling and also queue a post-reflow callback + // to ensure that restyle and reflow happens immediately after the current + // reflow. + void + SetIncrementScriptLevel(PRInt32 aChildIndex, PRBool aIncrement); // -------------------------------------------------------------------------- // Overloaded nsHTMLContainerFrame methods -- see documentation in nsIFrame.h @@ -125,11 +119,6 @@ public: nsHTMLContainerFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML)); } - NS_IMETHOD - Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow); - NS_IMETHOD AppendFrames(nsIAtom* aListName, nsIFrame* aFrameList); @@ -252,17 +241,10 @@ public: nsBoundingMetrics& aBoundingMetrics, eMathMLFrameType* aMathMLFrameType = nsnull); - // helper to let the scriptstyle re-resolution pass through - // a subtree that may contain non-MathML container frames - static void - PropagateScriptStyleFor(nsIFrame* aFrame, - PRInt32 aParentScriptLevel); - // helper to let the update of presentation data pass through // a subtree that may contain non-MathML container frames static void PropagatePresentationDataFor(nsIFrame* aFrame, - PRInt32 aScriptLevelIncrement, PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate); @@ -270,7 +252,6 @@ public: PropagatePresentationDataFromChildAt(nsIFrame* aParentFrame, PRInt32 aFirstChildIndex, PRInt32 aLastChildIndex, - PRInt32 aScriptLevelIncrement, PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate); @@ -352,24 +333,10 @@ public: NS_ASSERTION(!aListName, "unexpected frame list"); nsresult rv = nsBlockFrame::SetInitialChildList(aListName, aChildList); // re-resolve our subtree to set any mathml-expected data - nsMathMLContainerFrame::MapCommonAttributesIntoCSS(PresContext(), this); nsMathMLContainerFrame::RebuildAutomaticDataForChildren(this); return rv; } - NS_IMETHOD - Reflow(nsPresContext* aPresContext, - nsHTMLReflowMetrics& aDesiredSize, - const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus) - { - if (mScriptStyleChanged) { - mScriptStyleChanged = PR_FALSE; - nsMathMLContainerFrame::PropagateScriptStyleFor(this, 0); - } - return nsBlockFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); - } - NS_IMETHOD AppendFrames(nsIAtom* aListName, nsIFrame* aFrameList) @@ -421,15 +388,6 @@ protected: AddStateBits(NS_BLOCK_SPACE_MGR); } virtual ~nsMathMLmathBlockFrame() {} - - NS_IMETHOD - DidSetStyleContext() - { - mScriptStyleChanged = PR_TRUE; - return nsBlockFrame::DidSetStyleContext(); - } - - PRBool mScriptStyleChanged; }; // -------------- @@ -445,24 +403,10 @@ public: NS_ASSERTION(!aListName, "unexpected frame list"); nsresult rv = nsInlineFrame::SetInitialChildList(aListName, aChildList); // re-resolve our subtree to set any mathml-expected data - nsMathMLContainerFrame::MapCommonAttributesIntoCSS(PresContext(), this); nsMathMLContainerFrame::RebuildAutomaticDataForChildren(this); return rv; } - NS_IMETHOD - Reflow(nsPresContext* aPresContext, - nsHTMLReflowMetrics& aDesiredSize, - const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus) - { - if (mScriptStyleChanged) { - mScriptStyleChanged = PR_FALSE; - nsMathMLContainerFrame::PropagateScriptStyleFor(this, 0); - } - return nsInlineFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); - } - NS_IMETHOD AppendFrames(nsIAtom* aListName, nsIFrame* aFrameList) @@ -510,15 +454,6 @@ public: protected: nsMathMLmathInlineFrame(nsStyleContext* aContext) : nsInlineFrame(aContext) {} virtual ~nsMathMLmathInlineFrame() {} - - NS_IMETHOD - DidSetStyleContext() - { - mScriptStyleChanged = PR_TRUE; - return nsInlineFrame::DidSetStyleContext(); - } - - PRBool mScriptStyleChanged; }; #endif /* nsMathMLContainerFrame_h___ */ diff --git a/mozilla/layout/mathml/base/src/nsMathMLForeignFrameWrapper.h b/mozilla/layout/mathml/base/src/nsMathMLForeignFrameWrapper.h index c4a317cfc18..9bd21b34c76 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLForeignFrameWrapper.h +++ b/mozilla/layout/mathml/base/src/nsMathMLForeignFrameWrapper.h @@ -59,19 +59,11 @@ public: NS_IMETHOD UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, PRInt32 aLastIndex, - PRInt32 aScriptLevelIncrement, PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate) { nsMathMLContainerFrame::PropagatePresentationDataFromChildAt(this, - aFirstIndex, aLastIndex, aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); - return NS_OK; - } - - NS_IMETHOD - ReResolveScriptStyle(PRInt32 aParentScriptLevel) - { - nsMathMLContainerFrame::PropagateScriptStyleFor(this, aParentScriptLevel); + aFirstIndex, aLastIndex, aFlagsValues, aFlagsToUpdate); return NS_OK; } diff --git a/mozilla/layout/mathml/base/src/nsMathMLFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLFrame.cpp index 6c6516c77e1..fe5e790413d 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLFrame.cpp @@ -117,13 +117,11 @@ nsMathMLFrame::InheritAutomaticData(nsIFrame* aParent) mPresentationData.flags = 0; mPresentationData.baseFrame = nsnull; mPresentationData.mstyle = nsnull; - mPresentationData.scriptLevel = 0; - // by default, just inherit the display & scriptlevel of our parent + // by default, just inherit the display of our parent nsPresentationData parentData; GetPresentationDataFrom(aParent, parentData); mPresentationData.mstyle = parentData.mstyle; - mPresentationData.scriptLevel = parentData.scriptLevel; if (NS_MATHML_IS_DISPLAYSTYLE(parentData.flags)) { mPresentationData.flags |= NS_MATHML_DISPLAYSTYLE; } @@ -136,11 +134,9 @@ nsMathMLFrame::InheritAutomaticData(nsIFrame* aParent) } NS_IMETHODIMP -nsMathMLFrame::UpdatePresentationData(PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, +nsMathMLFrame::UpdatePresentationData(PRUint32 aFlagsValues, PRUint32 aWhichFlags) { - mPresentationData.scriptLevel += aScriptLevelIncrement; // update flags that are relevant to this call if (NS_MATHML_IS_DISPLAYSTYLE(aWhichFlags)) { // updating the displaystyle flag is allowed @@ -215,7 +211,6 @@ nsMathMLFrame::GetPresentationDataFrom(nsIFrame* aFrame, aPresentationData.flags = 0; aPresentationData.baseFrame = nsnull; aPresentationData.mstyle = nsnull; - aPresentationData.scriptLevel = 0; nsIFrame* frame = aFrame; while (frame) { @@ -351,106 +346,6 @@ nsMathMLFrame::GetAxisHeight(nsIRenderingContext& aRenderingContext, } } -// ================ -// Utilities for parsing and retrieving numeric values -// All returned values are in twips. - -/* -The REC says: - An explicit plus sign ('+') is not allowed as part of a numeric value - except when it is specifically listed in the syntax (as a quoted '+' or "+"), - - Units allowed - ID Description - em ems (font-relative unit traditionally used for horizontal lengths) - ex exs (font-relative unit traditionally used for vertical lengths) - px pixels, or pixel size of a "typical computer display" - in inches (1 inch = 2.54 centimeters) - cm centimeters - mm millimeters - pt points (1 point = 1/72 inch) - pc picas (1 pica = 12 points) - % percentage of default value - -Implementation here: - The numeric value is valid only if it is of the form [-] nnn.nnn [h/v-unit] -*/ - -/* static */ PRBool -nsMathMLFrame::ParseNumericValue(nsString& aString, - nsCSSValue& aCSSValue) -{ - aCSSValue.Reset(); - aString.CompressWhitespace(); // aString is not a const in this code... - - PRInt32 stringLength = aString.Length(); - if (!stringLength) - return PR_FALSE; - - nsAutoString number, unit; - - // see if the negative sign is there - PRInt32 i = 0; - PRUnichar c = aString[0]; - if (c == '-') { - number.Append(c); - i++; - - // skip any space after the negative sign - if (i < stringLength && nsCRT::IsAsciiSpace(aString[i])) - i++; - } - - // Gather up characters that make up the number - PRBool gotDot = PR_FALSE; - for ( ; i < stringLength; i++) { - c = aString[i]; - if (gotDot && c == '.') - return PR_FALSE; // two dots encountered - else if (c == '.') - gotDot = PR_TRUE; - else if (!nsCRT::IsAsciiDigit(c)) { - aString.Right(unit, stringLength - i); - unit.CompressWhitespace(); // some authors leave blanks before the unit - break; - } - number.Append(c); - } - - // on exit, also return a nicer string version of the value in case - // the caller wants it (e.g., this removes whitespace before units) - aString.Assign(number); - aString.Append(unit); - - // Convert number to floating point - PRInt32 errorCode; - float floatValue = number.ToFloat(&errorCode); - if (errorCode) - return PR_FALSE; - - nsCSSUnit cssUnit; - if (unit.IsEmpty()) { - cssUnit = eCSSUnit_Number; // no explicit unit, this is a number that will act as a multiplier - } - else if (unit.EqualsLiteral("%")) { - aCSSValue.SetPercentValue(floatValue / 100.0f); - return PR_TRUE; - } - else if (unit.EqualsLiteral("em")) cssUnit = eCSSUnit_EM; - else if (unit.EqualsLiteral("ex")) cssUnit = eCSSUnit_XHeight; - else if (unit.EqualsLiteral("px")) cssUnit = eCSSUnit_Pixel; - else if (unit.EqualsLiteral("in")) cssUnit = eCSSUnit_Inch; - else if (unit.EqualsLiteral("cm")) cssUnit = eCSSUnit_Centimeter; - else if (unit.EqualsLiteral("mm")) cssUnit = eCSSUnit_Millimeter; - else if (unit.EqualsLiteral("pt")) cssUnit = eCSSUnit_Point; - else if (unit.EqualsLiteral("pc")) cssUnit = eCSSUnit_Pica; - else // unexpected unit - return PR_FALSE; - - aCSSValue.SetFloatValue(floatValue, cssUnit); - return PR_TRUE; -} - /* static */ nscoord nsMathMLFrame::CalcLength(nsPresContext* aPresContext, nsStyleContext* aStyleContext, @@ -560,247 +455,6 @@ nsCSSMapping { const char* cssProperty; }; -static void -GetMathMLAttributeStyleSheet(nsPresContext* aPresContext, - nsIStyleSheet** aSheet) -{ - static const char kTitle[] = "Internal MathML/CSS Attribute Style Sheet"; - *aSheet = nsnull; - - // first, look if the attribute stylesheet is already there - nsStyleSet *styleSet = aPresContext->StyleSet(); - NS_ASSERTION(styleSet, "no style set"); - - nsAutoString title; - for (PRInt32 i = styleSet->SheetCount(nsStyleSet::eAgentSheet) - 1; - i >= 0; --i) { - nsIStyleSheet *sheet = styleSet->StyleSheetAt(nsStyleSet::eAgentSheet, i); - nsCOMPtr cssSheet(do_QueryInterface(sheet)); - if (cssSheet) { - cssSheet->GetTitle(title); - if (title.Equals(NS_ConvertASCIItoUTF16(kTitle))) { - *aSheet = sheet; - NS_IF_ADDREF(*aSheet); - return; - } - } - } - - // then, create a new one if it isn't yet there - nsCOMPtr uri; - NS_NewURI(getter_AddRefs(uri), "about:internal-mathml-attribute-stylesheet"); - if (!uri) - return; - nsCOMPtr cssSheet(do_CreateInstance(kCSSStyleSheetCID)); - if (!cssSheet) - return; - cssSheet->SetURIs(uri, nsnull, uri); - cssSheet->SetTitle(NS_ConvertASCIItoUTF16(kTitle)); - // all done, no further activity from the net involved, so we better do this - cssSheet->SetComplete(); - - nsCOMPtr domSheet(do_QueryInterface(cssSheet)); - if (domSheet) { - PRUint32 index; - domSheet->InsertRule(NS_LITERAL_STRING("@namespace url(http://www.w3.org/1998/Math/MathML);"), - 0, &index); - } - - // insert the stylesheet into the styleset without notifying observers - // XXX Should this be at a different level? - styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, cssSheet); - *aSheet = cssSheet; - NS_ADDREF(*aSheet); -} - -/* static */ PRInt32 -nsMathMLFrame::MapCommonAttributesIntoCSS(nsPresContext* aPresContext, - nsIContent* aContent) -{ - // normal case, quick return if there are no attributes - NS_ASSERTION(aContent, "null arg"); - PRUint32 attrCount = 0; - if (aContent) - attrCount = aContent->GetAttrCount(); - if (!attrCount) - return 0; - - // need to initialize here -- i.e., after registering nsGkAtoms - static const nsCSSMapping - kCSSMappingTable[] = { - {kMathMLversion2, nsGkAtoms::mathcolor_, "color:"}, - {kMathMLversion1, nsGkAtoms::color, "color:"}, - {kMathMLversion2, nsGkAtoms::mathsize_, "font-size:"}, - {kMathMLversion1, nsGkAtoms::fontsize_, "font-size:"}, - {kMathMLversion1, nsGkAtoms::fontfamily_, "font-family:"}, - {kMathMLversion2, nsGkAtoms::mathbackground_, "background-color:"}, - {kMathMLversion1, nsGkAtoms::background, "background-color:"}, - {0, nsnull, nsnull} - }; - - nsCOMPtr doc; - nsCOMPtr sheet; - nsCOMPtr cssSheet; - nsCOMPtr domSheet; - - PRInt32 ruleCount = 0; - for (PRUint32 i = 0; i < attrCount; ++i) { - const nsAttrName* name = aContent->GetAttrNameAt(i); - if (name->NamespaceID() != kNameSpaceID_None) - continue; - - nsIAtom* attrAtom = name->LocalName(); - - // lookup the equivalent CSS property - const nsCSSMapping* map = kCSSMappingTable; - while (map->attrAtom && map->attrAtom != attrAtom) - ++map; - if (!map->attrAtom) - continue; - nsAutoString cssProperty(NS_ConvertASCIItoUTF16(map->cssProperty)); - - nsAutoString attrValue; - aContent->GetAttr(kNameSpaceID_None, attrAtom, attrValue); - if (attrValue.IsEmpty()) - continue; - nsAutoString escapedAttrValue; - nsStyleUtil::EscapeCSSString(attrValue, escapedAttrValue); - - // don't add rules that are already in mathml.css - // (this will also clean up whitespace before units - see bug 125303) - if (attrAtom == nsGkAtoms::fontsize_ || attrAtom == nsGkAtoms::mathsize_) { - nsCSSValue cssValue; - nsAutoString numericValue(attrValue); - if (!ParseNumericValue(numericValue, cssValue)) - continue; - // on exit, ParseNumericValue also returns a nicer string - // in which the whitespace before the unit is cleaned up - cssProperty.Append(numericValue); - } - else - cssProperty.Append(attrValue); - - nsAutoString attrName; - attrAtom->ToString(attrName); - - // make a style rule that maps to the equivalent CSS property - nsAutoString selector, cssRule; - selector.Assign(NS_LITERAL_STRING("[") + attrName + - NS_LITERAL_STRING("=\"") + escapedAttrValue + - NS_LITERAL_STRING("\"]")); - cssRule.Assign(selector + - NS_LITERAL_STRING("{") + cssProperty + NS_LITERAL_STRING("}")); - - if (!sheet) { - // first time... we do this to defer the lookup up to the - // point where we encounter attributes that actually matter - doc = aContent->GetDocument(); - if (!doc) - return 0; - GetMathMLAttributeStyleSheet(aPresContext, getter_AddRefs(sheet)); - if (!sheet) - return 0; - // by construction, these cannot be null at this point - cssSheet = do_QueryInterface(sheet); - domSheet = do_QueryInterface(sheet); - NS_ASSERTION(cssSheet && domSheet, "unexpected null pointers"); - // we will keep the sheet orphan as we populate it. This way, - // observers of the document won't be notified and we avoid any troubles - // that may come from reconstructing the frame tree. Our rules only need - // a re-resolve of style data and a reflow, not a reconstruct-all... - sheet->SetOwningDocument(nsnull); - } - - // check for duplicate, if a similar rule is already there, - // don't bother to add another one - PRInt32 k, count; - cssSheet->StyleRuleCount(count); - for (k = 0; k < count; ++k) { - nsAutoString tmpSelector; - nsCOMPtr tmpRule; - cssSheet->GetStyleRuleAt(k, *getter_AddRefs(tmpRule)); - nsCOMPtr tmpStyleRule = do_QueryInterface(tmpRule); - if (tmpStyleRule) { - tmpStyleRule->GetSelectorText(tmpSelector); - NS_ASSERTION(tmpSelector.CharAt(0) != '*', "unexpected universal symbol"); -#ifdef DEBUG_rbs - nsCAutoString str; - LossyAppendUTF16toASCII(selector, str); - str.AppendLiteral(" vs "); - LossyAppendUTF16toASCII(tmpSelector, str); - printf("Attr selector %s %s\n", str.get(), - tmpSelector.Equals(selector)? " ... match" : " ... nomatch"); -#endif - if (tmpSelector.Equals(selector)) { - k = -1; - break; - } - } - } - if (k >= 0) { - // insert the rule (note: when the sheet already has @namespace and - // friends, insert after them, e.g., at the end, otherwise it won't work) - // For MathML 2, insert at the end to give it precedence - PRInt32 pos = (map->compatibility == kMathMLversion2) ? count : 1; - PRUint32 index; - domSheet->InsertRule(cssRule, pos, &index); - ++ruleCount; - } - } - // restore the sheet to its owner - if (sheet) { - sheet->SetOwningDocument(doc); - } - - return ruleCount; -} - -/* static */ PRInt32 -nsMathMLFrame::MapCommonAttributesIntoCSS(nsPresContext* aPresContext, - nsIFrame* aFrame) -{ - PRInt32 ruleCount = MapCommonAttributesIntoCSS(aPresContext, aFrame->GetContent()); - if (!ruleCount) - return 0; - - // now, re-resolve the style contexts in our subtree - nsFrameManager *fm = aPresContext->FrameManager(); - nsStyleChangeList changeList; - fm->ComputeStyleChangeFor(aFrame, &changeList, NS_STYLE_HINT_NONE); -#ifdef DEBUG - // Use the parent frame to make sure we catch in-flows and such - nsIFrame* parentFrame = aFrame->GetParent(); - fm->DebugVerifyStyleTree(parentFrame ? parentFrame : aFrame); -#endif - - return ruleCount; -} - -/* static */ PRBool -nsMathMLFrame::CommonAttributeChangedFor(nsPresContext* aPresContext, - nsIContent* aContent, - nsIAtom* aAttribute) -{ - if (aAttribute == nsGkAtoms::mathcolor_ || - aAttribute == nsGkAtoms::color || - aAttribute == nsGkAtoms::mathsize_ || - aAttribute == nsGkAtoms::fontsize_ || - aAttribute == nsGkAtoms::fontfamily_ || - aAttribute == nsGkAtoms::mathbackground_ || - aAttribute == nsGkAtoms::background) { - - MapCommonAttributesIntoCSS(aPresContext, aContent); - - // That's all folks. Common attributes go in the internal MathML attribute - // stylesheet. So when nsCSSFrameConstructor checks if the content - // HasAttributeDependentStyle(), it will detect them and issue a - // PostRestyleEvent() to re-resolve the style data and reflow if needed. - return PR_TRUE; - } - - return PR_FALSE; -} - #if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX) class nsDisplayMathMLBoundingMetrics : public nsDisplayItem { public: diff --git a/mozilla/layout/mathml/base/src/nsMathMLFrame.h b/mozilla/layout/mathml/base/src/nsMathMLFrame.h index 5a0b8eaaed7..05e41030681 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLFrame.h +++ b/mozilla/layout/mathml/base/src/nsMathMLFrame.h @@ -49,6 +49,7 @@ #include "nsIMathMLFrame.h" #include "nsFrame.h" #include "nsCSSValue.h" +#include "nsMathMLElement.h" class nsMathMLChar; @@ -149,26 +150,18 @@ public: } NS_IMETHOD - UpdatePresentationData(PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, + UpdatePresentationData(PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate); NS_IMETHOD UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, PRInt32 aLastIndex, - PRInt32 aScriptLevelIncrement, PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate) { return NS_OK; } - NS_IMETHOD - ReResolveScriptStyle(PRInt32 aParentScriptLevel) - { - return NS_OK; - } - // helper to give a style context suitable for doing the stretching to the // MathMLChar. Frame classes that use this should make the extra style contexts // accessible to the Style System via Get/Set AdditionalStyleContext. @@ -223,8 +216,10 @@ public: // utilities to parse and retrieve numeric values in CSS units // All values are stored in twips. static PRBool - ParseNumericValue(nsString& aString, - nsCSSValue& aCSSValue); + ParseNumericValue(const nsString& aString, + nsCSSValue& aCSSValue) { + return nsMathMLElement::ParseNumericValue(aString, aCSSValue, PR_FALSE); + } static nscoord CalcLength(nsPresContext* aPresContext, @@ -433,24 +428,6 @@ public: nsIFontMetrics* aFontMetrics, nscoord& aAxisHeight); - // ================ - // helpers to map attributes into CSS rules (work-around to bug 69409 which - // is not scheduled to be fixed anytime soon) - static PRInt32 - MapCommonAttributesIntoCSS(nsPresContext* aPresContext, - nsIContent* aContent); - static PRInt32 - MapCommonAttributesIntoCSS(nsPresContext* aPresContext, - nsIFrame* aFrame); - - // helper used by all AttributeChanged() methods. It handles - // those attributes that are common to all tags. - // @return true if the attribue is handled. - static PRBool - CommonAttributeChangedFor(nsPresContext* aPresContext, - nsIContent* aContent, - nsIAtom* aAttribute); - protected: #if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX) nsresult DisplayBoundingMetrics(nsDisplayListBuilder* aBuilder, diff --git a/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.cpp index 91009c63a13..976a42a926e 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.cpp @@ -267,7 +267,8 @@ nsMathMLmfencedFrame::doReflow(nsPresContext* aPresContext, PRInt32 i; nsCOMPtr fm; - aReflowState.rendContext->SetFont(aForFrame->GetStyleFont()->mFont, nsnull); + const nsStyleFont* font = aForFrame->GetStyleFont(); + aReflowState.rendContext->SetFont(font->mFont, nsnull); aReflowState.rendContext->GetFontMetrics(*getter_AddRefs(fm)); nscoord axisHeight, em; GetAxisHeight(*aReflowState.rendContext, fm, axisHeight); @@ -390,19 +391,19 @@ nsMathMLmfencedFrame::doReflow(nsPresContext* aPresContext, ///////////////// // opening fence ... ReflowChar(aPresContext, *aReflowState.rendContext, aOpenChar, - NS_MATHML_OPERATOR_FORM_PREFIX, presentationData.scriptLevel, + NS_MATHML_OPERATOR_FORM_PREFIX, font->mScriptLevel, axisHeight, leading, em, containerSize, ascent, descent); ///////////////// // separators ... for (i = 0; i < aSeparatorsCount; i++) { ReflowChar(aPresContext, *aReflowState.rendContext, &aSeparatorsChar[i], - NS_MATHML_OPERATOR_FORM_INFIX, presentationData.scriptLevel, + NS_MATHML_OPERATOR_FORM_INFIX, font->mScriptLevel, axisHeight, leading, em, containerSize, ascent, descent); } ///////////////// // closing fence ... ReflowChar(aPresContext, *aReflowState.rendContext, aCloseChar, - NS_MATHML_OPERATOR_FORM_POSTFIX, presentationData.scriptLevel, + NS_MATHML_OPERATOR_FORM_POSTFIX, font->mScriptLevel, axisHeight, leading, em, containerSize, ascent, descent); ////////////////// diff --git a/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.cpp index 3669cc16630..9a3d663b9e4 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.cpp @@ -130,13 +130,14 @@ nsMathMLmfracFrame::TransmitAutomaticData() // false increments scriptlevel by 1, within numerator and denominator. // 2. The TeXbook (Ch 17. p.141) says the numerator inherits the compression // while the denominator is compressed - PRInt32 increment = - NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags) ? 0 : 1; - mInnerScriptLevel = mPresentationData.scriptLevel + increment; - UpdatePresentationDataFromChildAt(0, -1, increment, + SetIncrementScriptLevel(0, !NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)); + // XXXroc how come point 1 above says we should increment scriptlevel for + // the denominator, but the old code didn't? + + UpdatePresentationDataFromChildAt(0, -1, ~NS_MATHML_DISPLAYSTYLE, NS_MATHML_DISPLAYSTYLE); - UpdatePresentationDataFromChildAt(1, 1, 0, + UpdatePresentationDataFromChildAt(1, 1, NS_MATHML_COMPRESSED, NS_MATHML_COMPRESSED); @@ -477,55 +478,9 @@ nsMathMLmfracFrame::AttributeChanged(PRInt32 aNameSpaceID, AttributeChanged(aNameSpaceID, aAttribute, aModType); } -NS_IMETHODIMP -nsMathMLmfracFrame::UpdatePresentationData(PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, - PRUint32 aFlagsToUpdate) -{ - // mfrac is special... The REC says: - // The element sets displaystyle to "false", or if it was already - // false increments scriptlevel by 1, within numerator and denominator. - // @see similar peculiarities for , , - - // This means that - // 1. If our displaystyle is being changed from true to false, we have - // to propagate an inner scriptlevel increment to our children - // 2. If the displaystyle is changed from false to true, we have to undo - // any incrementation that was done on the inner scriptlevel - - if (NS_MATHML_IS_DISPLAYSTYLE(aFlagsToUpdate)) { - if (mInnerScriptLevel > mPresentationData.scriptLevel) { - // we get here if our displaystyle is currently false - NS_ASSERTION(!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags), "out of sync"); - if (NS_MATHML_IS_DISPLAYSTYLE(aFlagsValues)) { - // ...and is being set to true, so undo the inner increment now - mInnerScriptLevel = mPresentationData.scriptLevel; - UpdatePresentationDataFromChildAt(0, -1, -1, 0, 0); - } - } - else { - // case of mInnerScriptLevel == mPresentationData.scriptLevel, our - // current displaystyle is true; we increment the inner scriptlevel if - // our displaystyle is about to be set to false; since mInnerScriptLevel - // is changed, we can only get here once - NS_ASSERTION(NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags), "out of sync"); - if (!NS_MATHML_IS_DISPLAYSTYLE(aFlagsValues)) { - mInnerScriptLevel = mPresentationData.scriptLevel + 1; - UpdatePresentationDataFromChildAt(0, -1, 1, 0, 0); - } - } - } - - mInnerScriptLevel += aScriptLevelIncrement; - return nsMathMLContainerFrame:: - UpdatePresentationData(aScriptLevelIncrement, aFlagsValues, - aFlagsToUpdate); -} - NS_IMETHODIMP nsMathMLmfracFrame::UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, PRInt32 aLastIndex, - PRInt32 aScriptLevelIncrement, PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate) { @@ -545,7 +500,7 @@ nsMathMLmfracFrame::UpdatePresentationDataFromChildAt(PRInt32 aFirstInde #endif return nsMathMLContainerFrame:: UpdatePresentationDataFromChildAt(aFirstIndex, aLastIndex, - aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); + aFlagsValues, aFlagsToUpdate); } // ---------------------- diff --git a/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.h b/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.h index d32f7ac7660..87e3592dde5 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.h +++ b/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.h @@ -124,15 +124,9 @@ public: NS_IMETHOD TransmitAutomaticData(); - NS_IMETHOD - UpdatePresentationData(PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, - PRUint32 aFlagsToUpdate); - NS_IMETHOD UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, PRInt32 aLastIndex, - PRInt32 aScriptLevelIncrement, PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate); @@ -157,7 +151,6 @@ protected: PRBool IsBevelled(); - PRInt32 mInnerScriptLevel; nsRect mLineRect; nsMathMLChar* mSlashChar; }; diff --git a/mozilla/layout/mathml/base/src/nsMathMLmmultiscriptsFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmmultiscriptsFrame.cpp index cccb4b6ec9f..23da493be49 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmmultiscriptsFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmmultiscriptsFrame.cpp @@ -73,7 +73,7 @@ nsMathMLmmultiscriptsFrame::TransmitAutomaticData() // The REC says: // The element increments scriptlevel by 1, and sets // displaystyle to "false", within each of its arguments except base - UpdatePresentationDataFromChildAt(1, -1, 1, + UpdatePresentationDataFromChildAt(1, -1, ~NS_MATHML_DISPLAYSTYLE, NS_MATHML_DISPLAYSTYLE); // The TeXbook (Ch 17. p.141) says the superscript inherits the compression @@ -106,7 +106,7 @@ nsMathMLmmultiscriptsFrame::TransmitAutomaticData() } for (PRInt32 i = subScriptFrames.Count() - 1; i >= 0; i--) { childFrame = (nsIFrame*)subScriptFrames[i]; - PropagatePresentationDataFor(childFrame, 0, + PropagatePresentationDataFor(childFrame, NS_MATHML_COMPRESSED, NS_MATHML_COMPRESSED); } @@ -158,7 +158,8 @@ nsMathMLmmultiscriptsFrame::Place(nsIRenderingContext& aRenderingContext, ProcessAttributes(); // get x-height (an ex) - aRenderingContext.SetFont(GetStyleFont()->mFont, nsnull); + const nsStyleFont* font = GetStyleFont(); + aRenderingContext.SetFont(font->mFont, nsnull); nsCOMPtr fm; aRenderingContext.GetFontMetrics(*getter_AddRefs(fm)); @@ -217,7 +218,7 @@ nsMathMLmmultiscriptsFrame::Place(nsIRenderingContext& aRenderingContext, // get sup script shift depending on current script level and display style // Rule 18c, App. G, TeXbook nscoord supScriptShift; - if ( mPresentationData.scriptLevel == 0 && + if ( font->mScriptLevel == 0 && NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags) && !NS_MATHML_IS_COMPRESSED(mPresentationData.flags)) { // Style D in TeXbook diff --git a/mozilla/layout/mathml/base/src/nsMathMLmoFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmoFrame.cpp index 2a697a0aff2..4193a614dbe 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmoFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmoFrame.cpp @@ -397,7 +397,7 @@ nsMathMLmoFrame::ProcessOperatorData() // tuning if we don't want too much extra space when we are a script. // (with its fonts, TeX sets lspace=0 & rspace=0 as soon as scriptlevel>0. // Our fonts can be anything, so...) - if (mPresentationData.scriptLevel > 0) { + if (GetStyleFont()->mScriptLevel > 0) { if (NS_MATHML_OPERATOR_EMBELLISH_IS_ISOLATED(mFlags)) { // could be an isolated accent or script, e.g., x^{+}, just zero out mEmbellishData.leftSpace = 0; diff --git a/mozilla/layout/mathml/base/src/nsMathMLmoverFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmoverFrame.cpp index 3e66a0f42f5..bf42708ac7c 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmoverFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmoverFrame.cpp @@ -82,12 +82,10 @@ nsMathMLmoverFrame::AttributeChanged(PRInt32 aNameSpaceID, } NS_IMETHODIMP -nsMathMLmoverFrame::UpdatePresentationData(PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, +nsMathMLmoverFrame::UpdatePresentationData(PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate) { - nsMathMLContainerFrame::UpdatePresentationData( - aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); + nsMathMLContainerFrame::UpdatePresentationData(aFlagsValues, aFlagsToUpdate); // disable the stretch-all flag if we are going to act like a superscript if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) && !NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) { @@ -102,7 +100,6 @@ nsMathMLmoverFrame::UpdatePresentationData(PRInt32 aScriptLevelIncrement NS_IMETHODIMP nsMathMLmoverFrame::UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, PRInt32 aLastIndex, - PRInt32 aScriptLevelIncrement, PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate) { @@ -126,8 +123,7 @@ nsMathMLmoverFrame::UpdatePresentationDataFromChildAt(PRInt32 aFirstInde aFlagsToUpdate &= ~NS_MATHML_DISPLAYSTYLE; aFlagsValues &= ~NS_MATHML_DISPLAYSTYLE; } - PropagatePresentationDataFor(childFrame, aScriptLevelIncrement, - aFlagsValues, aFlagsToUpdate); + PropagatePresentationDataFor(childFrame, aFlagsValues, aFlagsToUpdate); } index++; childFrame = childFrame->GetNextSibling(); @@ -219,11 +215,10 @@ XXX The winner is the outermost in conflicting settings like these: that math accents and \overline change uncramped styles to their cramped counterparts. */ - PRInt32 increment = NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags) - ? 0 : 1; + SetIncrementScriptLevel(1, !NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)); PRUint32 compress = NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags) ? NS_MATHML_COMPRESSED : 0; - PropagatePresentationDataFor(overscriptFrame, increment, + PropagatePresentationDataFor(overscriptFrame, ~NS_MATHML_DISPLAYSTYLE | compress, NS_MATHML_DISPLAYSTYLE | compress); diff --git a/mozilla/layout/mathml/base/src/nsMathMLmoverFrame.h b/mozilla/layout/mathml/base/src/nsMathMLmoverFrame.h index e5339319e16..c28e33e0991 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmoverFrame.h +++ b/mozilla/layout/mathml/base/src/nsMathMLmoverFrame.h @@ -64,14 +64,12 @@ public: TransmitAutomaticData(); NS_IMETHOD - UpdatePresentationData(PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, + UpdatePresentationData(PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate); NS_IMETHOD UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, PRInt32 aLastIndex, - PRInt32 aScriptLevelIncrement, PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate); diff --git a/mozilla/layout/mathml/base/src/nsMathMLmrootFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmrootFrame.cpp index fdeb5d380b2..0b153c7f2ea 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmrootFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmrootFrame.cpp @@ -111,10 +111,10 @@ nsMathMLmrootFrame::TransmitAutomaticData() // The element increments scriptlevel by 2, and sets displaystyle to // "false", within index, but leaves both attributes unchanged within base. // 2. The TeXbook (Ch 17. p.141) says \sqrt is compressed - UpdatePresentationDataFromChildAt(1, 1, 2, + UpdatePresentationDataFromChildAt(1, 1, ~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED, NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED); - UpdatePresentationDataFromChildAt(0, 0, 0, + UpdatePresentationDataFromChildAt(0, 0, NS_MATHML_COMPRESSED, NS_MATHML_COMPRESSED); return NS_OK; diff --git a/mozilla/layout/mathml/base/src/nsMathMLmsqrtFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmsqrtFrame.cpp index 20cffd82b5e..19587d7600e 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmsqrtFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmsqrtFrame.cpp @@ -124,7 +124,7 @@ nsMathMLmsqrtFrame::TransmitAutomaticData() // The element leaves both attributes [displaystyle and scriptlevel] // unchanged within all its arguments. // 2. The TeXBook (Ch 17. p.141) says that \sqrt is cramped - UpdatePresentationDataFromChildAt(0, -1, 0, + UpdatePresentationDataFromChildAt(0, -1, NS_MATHML_COMPRESSED, NS_MATHML_COMPRESSED); diff --git a/mozilla/layout/mathml/base/src/nsMathMLmstyleFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmstyleFrame.cpp index ab48344b2ed..1f2f81f2871 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmstyleFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmstyleFrame.cpp @@ -77,23 +77,6 @@ nsMathMLmstyleFrame::InheritAutomaticData(nsIFrame* aParent) // see if the displaystyle attribute is there nsMathMLFrame::FindAttrDisplaystyle(mContent, mPresentationData); - // see if the scriptlevel attribute is there - nsAutoString value; - mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::scriptlevel_, value); - if (!value.IsEmpty()) { - PRInt32 errorCode, userValue; - userValue = value.ToInteger(&errorCode); - if (!errorCode) { - if (value[0] != '+' && value[0] != '-') { // record that it is an explicit value - mPresentationData.flags |= NS_MATHML_EXPLICIT_SCRIPTLEVEL; - mPresentationData.scriptLevel = userValue; - } - else { - mPresentationData.scriptLevel += userValue; // incremental value... - } - } - } - return NS_OK; } @@ -112,8 +95,7 @@ nsMathMLmstyleFrame::TransmitAutomaticData() // Since UpdatePresentation() and UpdatePresentationDataFromChildAt() can be called // by a parent, ensure that the explicit attributes of take precedence NS_IMETHODIMP -nsMathMLmstyleFrame::UpdatePresentationData(PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, +nsMathMLmstyleFrame::UpdatePresentationData(PRUint32 aFlagsValues, PRUint32 aWhichFlags) { if (NS_MATHML_HAS_EXPLICIT_DISPLAYSTYLE(mPresentationData.flags)) { @@ -121,19 +103,13 @@ nsMathMLmstyleFrame::UpdatePresentationData(PRInt32 aScriptLevelIncremen aWhichFlags &= ~NS_MATHML_DISPLAYSTYLE; aFlagsValues &= ~NS_MATHML_DISPLAYSTYLE; } - if (NS_MATHML_HAS_EXPLICIT_SCRIPTLEVEL(mPresentationData.flags)) { - // our current state takes precedence, disallow updating the scriptlevel - aScriptLevelIncrement = 0; - } - return nsMathMLContainerFrame::UpdatePresentationData( - aScriptLevelIncrement, aFlagsValues, aWhichFlags); + return nsMathMLContainerFrame::UpdatePresentationData(aFlagsValues, aWhichFlags); } NS_IMETHODIMP nsMathMLmstyleFrame::UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, PRInt32 aLastIndex, - PRInt32 aScriptLevelIncrement, PRUint32 aFlagsValues, PRUint32 aWhichFlags) { @@ -142,16 +118,11 @@ nsMathMLmstyleFrame::UpdatePresentationDataFromChildAt(PRInt32 aFirstInd aWhichFlags &= ~NS_MATHML_DISPLAYSTYLE; aFlagsValues &= ~NS_MATHML_DISPLAYSTYLE; } - if (NS_MATHML_HAS_EXPLICIT_SCRIPTLEVEL(mPresentationData.flags)) { - // our current state takes precedence, disallow updating the scriptlevel - aScriptLevelIncrement = 0; - } // let the base class worry about the update return nsMathMLContainerFrame::UpdatePresentationDataFromChildAt( - aFirstIndex, aLastIndex, aScriptLevelIncrement, - aFlagsValues, aWhichFlags); + aFirstIndex, aLastIndex, aFlagsValues, aWhichFlags); } NS_IMETHODIMP @@ -159,10 +130,6 @@ nsMathMLmstyleFrame::AttributeChanged(PRInt32 aNameSpaceID, nsIAtom* aAttribute, PRInt32 aModType) { - // Attributes common to MathML tags - if (CommonAttributeChangedFor(PresContext(), mContent, aAttribute)) - return NS_OK; - // Other attributes can affect too many things, ask our parent to re-layout // its children so that we can pick up changes in our attributes & transmit // them in our subtree. However, our siblings will be re-laid too. We used diff --git a/mozilla/layout/mathml/base/src/nsMathMLmstyleFrame.h b/mozilla/layout/mathml/base/src/nsMathMLmstyleFrame.h index fb3eafccfa8..0bc9e2cd8d7 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmstyleFrame.h +++ b/mozilla/layout/mathml/base/src/nsMathMLmstyleFrame.h @@ -63,14 +63,12 @@ public: TransmitAutomaticData(); NS_IMETHOD - UpdatePresentationData(PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, + UpdatePresentationData(PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate); NS_IMETHOD UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, PRInt32 aLastIndex, - PRInt32 aScriptLevelIncrement, PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate); diff --git a/mozilla/layout/mathml/base/src/nsMathMLmsubFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmsubFrame.cpp index 4e380ab3826..340ec43e8c7 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmsubFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmsubFrame.cpp @@ -74,7 +74,7 @@ nsMathMLmsubFrame::TransmitAutomaticData() // The element increments scriptlevel by 1, and sets displaystyle to // "false", within subscript, but leaves both attributes unchanged within base. // 2. The TeXbook (Ch 17. p.141) says the subscript is compressed - UpdatePresentationDataFromChildAt(1, -1, 1, + UpdatePresentationDataFromChildAt(1, -1, ~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED, NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED); diff --git a/mozilla/layout/mathml/base/src/nsMathMLmsubsupFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmsubsupFrame.cpp index 55b9bfe151f..aa33cec9725 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmsubsupFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmsubsupFrame.cpp @@ -76,10 +76,10 @@ nsMathMLmsubsupFrame::TransmitAutomaticData() // unchanged within base. // 2. The TeXbook (Ch 17. p.141) says the superscript inherits the compression // while the subscript is compressed - UpdatePresentationDataFromChildAt(1, -1, 1, + UpdatePresentationDataFromChildAt(1, -1, ~NS_MATHML_DISPLAYSTYLE, NS_MATHML_DISPLAYSTYLE); - UpdatePresentationDataFromChildAt(1, 1, 0, + UpdatePresentationDataFromChildAt(1, 1, NS_MATHML_COMPRESSED, NS_MATHML_COMPRESSED); @@ -254,7 +254,7 @@ nsMathMLmsubsupFrame::PlaceSubSupScript(nsPresContext* aPresContext, nscoord supScriptShift; nsPresentationData presentationData; aFrame->GetPresentationData(presentationData); - if ( presentationData.scriptLevel == 0 && + if ( aFrame->GetStyleFont()->mScriptLevel == 0 && NS_MATHML_IS_DISPLAYSTYLE(presentationData.flags) && !NS_MATHML_IS_COMPRESSED(presentationData.flags)) { // Style D in TeXbook diff --git a/mozilla/layout/mathml/base/src/nsMathMLmsupFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmsupFrame.cpp index f7d97a24860..c36ee3b5b33 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmsupFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmsupFrame.cpp @@ -74,7 +74,7 @@ nsMathMLmsupFrame::TransmitAutomaticData() // "false", within superscript, but leaves both attributes unchanged within base. // 2. The TeXbook (Ch 17. p.141) says the superscript *inherits* the compression, // so we don't set the compression flag. Our parent will propagate its own. - UpdatePresentationDataFromChildAt(1, -1, 1, + UpdatePresentationDataFromChildAt(1, -1, ~NS_MATHML_DISPLAYSTYLE, NS_MATHML_DISPLAYSTYLE); @@ -190,7 +190,7 @@ nsMathMLmsupFrame::PlaceSuperScript(nsPresContext* aPresContext, nscoord supScriptShift; nsPresentationData presentationData; aFrame->GetPresentationData (presentationData); - if ( presentationData.scriptLevel == 0 && + if ( aFrame->GetStyleFont()->mScriptLevel == 0 && NS_MATHML_IS_DISPLAYSTYLE(presentationData.flags) && !NS_MATHML_IS_COMPRESSED(presentationData.flags)) { // Style D in TeXbook diff --git a/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.cpp index 5abaf2afe1d..f691a77e61f 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.cpp @@ -350,22 +350,12 @@ nsMathMLmtableOuterFrame::~nsMathMLmtableOuterFrame() { } -NS_IMETHODIMP -nsMathMLmtableOuterFrame::Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) -{ - nsresult rv = nsTableOuterFrame::Init(aContent, aParent, aPrevInFlow); - nsMathMLFrame::MapCommonAttributesIntoCSS(PresContext(), aContent); - return rv; -} - NS_IMETHODIMP nsMathMLmtableOuterFrame::InheritAutomaticData(nsIFrame* aParent) { // XXX the REC says that by default, displaystyle=false in - // let the base class inherit the scriptlevel and displaystyle from our parent + // let the base class inherit the displaystyle from our parent nsMathMLFrame::InheritAutomaticData(aParent); // see if the displaystyle attribute is there and let it override what we inherited @@ -379,8 +369,7 @@ nsMathMLmtableOuterFrame::InheritAutomaticData(nsIFrame* aParent) // Since UpdatePresentation() and UpdatePresentationDataFromChildAt() can be called // by a parent, ensure that the displaystyle attribute of mtable takes precedence NS_IMETHODIMP -nsMathMLmtableOuterFrame::UpdatePresentationData(PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, +nsMathMLmtableOuterFrame::UpdatePresentationData(PRUint32 aFlagsValues, PRUint32 aWhichFlags) { if (NS_MATHML_HAS_EXPLICIT_DISPLAYSTYLE(mPresentationData.flags)) { @@ -389,14 +378,12 @@ nsMathMLmtableOuterFrame::UpdatePresentationData(PRInt32 aScriptLevelIncrement, aFlagsValues &= ~NS_MATHML_DISPLAYSTYLE; } - return nsMathMLFrame::UpdatePresentationData( - aScriptLevelIncrement, aFlagsValues, aWhichFlags); + return nsMathMLFrame::UpdatePresentationData(aFlagsValues, aWhichFlags); } NS_IMETHODIMP nsMathMLmtableOuterFrame::UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, PRInt32 aLastIndex, - PRInt32 aScriptLevelIncrement, PRUint32 aFlagsValues, PRUint32 aWhichFlags) { @@ -407,7 +394,7 @@ nsMathMLmtableOuterFrame::UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex } nsMathMLContainerFrame::PropagatePresentationDataFromChildAt(this, - aFirstIndex, aLastIndex, aScriptLevelIncrement, aFlagsValues, aWhichFlags); + aFirstIndex, aLastIndex, aFlagsValues, aWhichFlags); return NS_OK; } @@ -417,10 +404,6 @@ nsMathMLmtableOuterFrame::AttributeChanged(PRInt32 aNameSpaceID, nsIAtom* aAttribute, PRInt32 aModType) { - // Attributes common to MathML tags - if (nsMathMLFrame::CommonAttributeChangedFor(PresContext(), mContent, aAttribute)) - return NS_OK; - // Attributes specific to : // frame : in mathml.css // framespacing : not yet supported @@ -456,7 +439,6 @@ nsMathMLmtableOuterFrame::AttributeChanged(PRInt32 aNameSpaceID, // presentational data, and issue a style-changed reflow request if (aAttribute == nsGkAtoms::displaystyle_) { nsMathMLContainerFrame::RebuildAutomaticDataForChildren(mParent); - nsMathMLContainerFrame::PropagateScriptStyleFor(tableFrame, mPresentationData.scriptLevel); // Need to reflow the parent, not us, because this can actually // affect siblings. PresContext()->PresShell()-> @@ -706,25 +688,11 @@ nsMathMLmtrFrame::~nsMathMLmtrFrame() { } -NS_IMETHODIMP -nsMathMLmtrFrame::Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) -{ - nsresult rv = nsTableRowFrame::Init(aContent, aParent, aPrevInFlow); - nsMathMLFrame::MapCommonAttributesIntoCSS(PresContext(), aContent); - return rv; -} - NS_IMETHODIMP nsMathMLmtrFrame::AttributeChanged(PRInt32 aNameSpaceID, nsIAtom* aAttribute, PRInt32 aModType) { - // Attributes common to MathML tags - if (nsMathMLFrame::CommonAttributeChangedFor(PresContext(), mContent, aAttribute)) - return NS_OK; - // Attributes specific to : // groupalign : Not yet supported. // rowalign : Fully specified in mathml.css, and so HasAttributeDependentStyle() will @@ -781,16 +749,6 @@ nsMathMLmtdFrame::~nsMathMLmtdFrame() { } -NS_IMETHODIMP -nsMathMLmtdFrame::Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) -{ - nsresult rv = nsTableCellFrame::Init(aContent, aParent, aPrevInFlow); - nsMathMLFrame::MapCommonAttributesIntoCSS(PresContext(), aContent); - return rv; -} - PRInt32 nsMathMLmtdFrame::GetRowSpan() { @@ -834,10 +792,6 @@ nsMathMLmtdFrame::AttributeChanged(PRInt32 aNameSpaceID, nsIAtom* aAttribute, PRInt32 aModType) { - // Attributes common to MathML tags - if (nsMathMLFrame::CommonAttributeChangedFor(PresContext(), mContent, aAttribute)) - return NS_OK; - // Attributes specific to : // groupalign : Not yet supported // rowalign : in mathml.css diff --git a/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.h b/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.h index bbf0322c505..5bfbb23f045 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.h +++ b/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.h @@ -60,31 +60,17 @@ public: InheritAutomaticData(nsIFrame* aParent); NS_IMETHOD - UpdatePresentationData(PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, + UpdatePresentationData(PRUint32 aFlagsValues, PRUint32 aWhichFlags); NS_IMETHOD UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, PRInt32 aLastIndex, - PRInt32 aScriptLevelIncrement, PRUint32 aFlagsValues, PRUint32 aWhichFlags); - NS_IMETHOD - ReResolveScriptStyle(PRInt32 aParentScriptLevel) - { - nsMathMLContainerFrame::PropagateScriptStyleFor(this, aParentScriptLevel); - return NS_OK; - } - // overloaded nsTableOuterFrame methods - NS_IMETHOD - Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow); - NS_IMETHOD Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, @@ -182,11 +168,6 @@ public: // overloaded nsTableRowFrame methods - NS_IMETHOD - Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow); - NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID, nsIAtom* aAttribute, @@ -251,11 +232,6 @@ public: // overloaded nsTableCellFrame methods - NS_IMETHOD - Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow); - NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID, nsIAtom* aAttribute, @@ -287,19 +263,11 @@ public: NS_IMETHOD UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, PRInt32 aLastIndex, - PRInt32 aScriptLevelIncrement, PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate) { nsMathMLContainerFrame::PropagatePresentationDataFromChildAt(this, - aFirstIndex, aLastIndex, aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); - return NS_OK; - } - - NS_IMETHOD - ReResolveScriptStyle(PRInt32 aParentScriptLevel) - { - nsMathMLContainerFrame::PropagateScriptStyleFor(this, aParentScriptLevel); + aFirstIndex, aLastIndex, aFlagsValues, aFlagsToUpdate); return NS_OK; } diff --git a/mozilla/layout/mathml/base/src/nsMathMLmunderFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmunderFrame.cpp index 56f2e637a94..2ffd7e01674 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmunderFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmunderFrame.cpp @@ -82,12 +82,10 @@ nsMathMLmunderFrame::AttributeChanged(PRInt32 aNameSpaceID, } NS_IMETHODIMP -nsMathMLmunderFrame::UpdatePresentationData(PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, +nsMathMLmunderFrame::UpdatePresentationData(PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate) { - nsMathMLContainerFrame::UpdatePresentationData( - aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); + nsMathMLContainerFrame::UpdatePresentationData(aFlagsValues, aFlagsToUpdate); // disable the stretch-all flag if we are going to act like a subscript if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) && !NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) { @@ -102,7 +100,6 @@ nsMathMLmunderFrame::UpdatePresentationData(PRInt32 aScriptLevelIncremen NS_IMETHODIMP nsMathMLmunderFrame::UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, PRInt32 aLastIndex, - PRInt32 aScriptLevelIncrement, PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate) { @@ -126,8 +123,7 @@ nsMathMLmunderFrame::UpdatePresentationDataFromChildAt(PRInt32 aFirstInd aFlagsToUpdate &= ~NS_MATHML_DISPLAYSTYLE; aFlagsValues &= ~NS_MATHML_DISPLAYSTYLE; } - PropagatePresentationDataFor(childFrame, - aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); + PropagatePresentationDataFor(childFrame, aFlagsValues, aFlagsToUpdate); } index++; childFrame = childFrame->GetNextSibling(); @@ -217,9 +213,8 @@ XXX The winner is the outermost setting in conflicting settings like these: The TeXBook treats 'under' like a subscript, so p.141 or Rule 13a say it should be compressed */ - PRInt32 increment = NS_MATHML_EMBELLISH_IS_ACCENTUNDER(mEmbellishData.flags) - ? 0 : 1; - PropagatePresentationDataFor(underscriptFrame, increment, + SetIncrementScriptLevel(1, !NS_MATHML_EMBELLISH_IS_ACCENTUNDER(mEmbellishData.flags)); + PropagatePresentationDataFor(underscriptFrame, ~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED, NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED); diff --git a/mozilla/layout/mathml/base/src/nsMathMLmunderFrame.h b/mozilla/layout/mathml/base/src/nsMathMLmunderFrame.h index 706da06f7e7..0126fe70fea 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmunderFrame.h +++ b/mozilla/layout/mathml/base/src/nsMathMLmunderFrame.h @@ -64,14 +64,12 @@ public: TransmitAutomaticData(); NS_IMETHOD - UpdatePresentationData(PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, + UpdatePresentationData(PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate); NS_IMETHOD UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, PRInt32 aLastIndex, - PRInt32 aScriptLevelIncrement, PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate); diff --git a/mozilla/layout/mathml/base/src/nsMathMLmunderoverFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmunderoverFrame.cpp index 8b00a2eee01..6e93454cfa2 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmunderoverFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmunderoverFrame.cpp @@ -83,12 +83,10 @@ nsMathMLmunderoverFrame::AttributeChanged(PRInt32 aNameSpaceID, } NS_IMETHODIMP -nsMathMLmunderoverFrame::UpdatePresentationData(PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, +nsMathMLmunderoverFrame::UpdatePresentationData(PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate) { - nsMathMLContainerFrame::UpdatePresentationData(aScriptLevelIncrement, - aFlagsValues, aFlagsToUpdate); + nsMathMLContainerFrame::UpdatePresentationData(aFlagsValues, aFlagsToUpdate); // disable the stretch-all flag if we are going to act like a subscript-superscript pair if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) && !NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) { @@ -103,7 +101,6 @@ nsMathMLmunderoverFrame::UpdatePresentationData(PRInt32 aScriptLevelIncr NS_IMETHODIMP nsMathMLmunderoverFrame::UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, PRInt32 aLastIndex, - PRInt32 aScriptLevelIncrement, PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate) { @@ -132,8 +129,7 @@ nsMathMLmunderoverFrame::UpdatePresentationDataFromChildAt(PRInt32 aFirs aFlagsToUpdate &= ~NS_MATHML_DISPLAYSTYLE; aFlagsValues &= ~NS_MATHML_DISPLAYSTYLE; } - PropagatePresentationDataFor(childFrame, - aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); + PropagatePresentationDataFor(childFrame, aFlagsValues, aFlagsToUpdate); } index++; childFrame = childFrame->GetNextSibling(); @@ -242,11 +238,10 @@ nsMathMLmunderoverFrame::TransmitAutomaticData() that math accents and \overline change uncramped styles to their cramped counterparts. */ - PRInt32 increment = NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags) - ? 0 : 1; PRUint32 compress = NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags) ? NS_MATHML_COMPRESSED : 0; - PropagatePresentationDataFor(overscriptFrame, increment, + SetIncrementScriptLevel(2, !NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)); + PropagatePresentationDataFor(overscriptFrame, ~NS_MATHML_DISPLAYSTYLE | compress, NS_MATHML_DISPLAYSTYLE | compress); @@ -254,9 +249,8 @@ nsMathMLmunderoverFrame::TransmitAutomaticData() The TeXBook treats 'under' like a subscript, so p.141 or Rule 13a say it should be compressed */ - increment = NS_MATHML_EMBELLISH_IS_ACCENTUNDER(mEmbellishData.flags) - ? 0 : 1; - PropagatePresentationDataFor(underscriptFrame, increment, + SetIncrementScriptLevel(1, !NS_MATHML_EMBELLISH_IS_ACCENTUNDER(mEmbellishData.flags)); + PropagatePresentationDataFor(underscriptFrame, ~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED, NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED); diff --git a/mozilla/layout/mathml/base/src/nsMathMLmunderoverFrame.h b/mozilla/layout/mathml/base/src/nsMathMLmunderoverFrame.h index 06de1b5e517..4456e08fe03 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmunderoverFrame.h +++ b/mozilla/layout/mathml/base/src/nsMathMLmunderoverFrame.h @@ -64,14 +64,12 @@ public: TransmitAutomaticData(); NS_IMETHOD - UpdatePresentationData(PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, + UpdatePresentationData(PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate); NS_IMETHOD UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, PRInt32 aLastIndex, - PRInt32 aScriptLevelIncrement, PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate); diff --git a/mozilla/layout/mathml/content/src/mathml.css b/mozilla/layout/mathml/content/src/mathml.css index 1d585d7ca54..385d7c6a3c9 100644 --- a/mozilla/layout/mathml/content/src/mathml.css +++ b/mozilla/layout/mathml/content/src/mathml.css @@ -84,40 +84,6 @@ math[display="inline"] { [-moz-math-font-style="invariant"] { font-style: normal; /* a non-stylable character preserves its own style */ } -/* change of size induced by changing the scriptlevel */ -[-moz-math-font-size="+1"] { - font-size: 71%; -} -[-moz-math-font-size="+2"] { - font-size: 50%; -} -[-moz-math-font-size="+3"] { - font-size: 36%; -} -[-moz-math-font-size="+4"] { - font-size: 25%; -} -[-moz-math-font-size="+5"] { - font-size: 18%; -} -[-moz-math-font-size="scriptminsize"] { - font-size: 8pt; -} -[-moz-math-font-size="-1"] { - font-size: 141%; -} -[-moz-math-font-size="-2"] { - font-size: 200%; -} -[-moz-math-font-size="-3"] { - font-size: 283%; -} -[-moz-math-font-size="-4"] { - font-size: 400%; -} -[-moz-math-font-size="-5"] { - font-size: 566%; -} /**************************************************************************/ /* attributes common to all tags */ @@ -139,34 +105,6 @@ math[display="inline"] { [fontweight="bold"] { font-weight: bold; } -/* fontsize */ -[fontsize="xx-small"] { - font-size: xx-small; -} -[fontsize="x-small"] { - font-size: x-small; -} -[fontsize="small"] { - font-size: small; -} -[fontsize="smaller"] { - font-size: smaller; -} -[fontsize="medium"] { - font-size: medium; -} -[fontsize="large"] { - font-size: large; -} -[fontsize="larger"] { - font-size: larger; -} -[fontsize="x-large"] { - font-size: x-large; -} -[fontsize="xx-large"] { - font-size: xx-large; -} /* attributes from MathML 2.0 */ @@ -176,14 +114,6 @@ math[display="inline"] { mathbackground (replaces 'background'): #rgb | #rrggbb | html-color-name */ -/* mathsize (replaces 'fontsize'): - small, big, number v-unit (a numeric value is handled in the back-end) */ -[mathsize="small"] { - font-size: small; -} -[mathsize="big"] { - font-size: large; -} /* mathvariant (replaces 'fontstyle' & 'fontweight' & 'fontslant'): normal | bold | italic | bold-italic | double-struck | bold-fraktur | script | bold-script | fraktur | sans-serif | bold-sans-serif | sans-serif-italic | @@ -481,3 +411,21 @@ semantics > :not(:first-child) { display: inline-block !important; position: static !important; } + +/*****************************************/ +/* Controlling scriptlevel */ +/*****************************************/ + +/* mfrac, munder, mover and munderover change the scriptlevels of their children using + -moz-math-increment-script-level because regular CSS rules are insufficient to + control when the scriptlevel should be incremented */ +:-moz-math-increment-script-level { -moz-script-level:+1; } + +/* all other cases can be described using regular CSS, so we do it this way because it's + more efficient and less code */ +mroot > :not(:first-child) { -moz-script-level:+2; } + +msub > :not(:first-child), +msup > :not(:first-child), +msubsup > :not(:first-child), +mmultiscripts > :not(:first-child) { -moz-script-level:+1; } diff --git a/mozilla/layout/reftests/bugs/355548-1-ref.xml b/mozilla/layout/reftests/bugs/355548-1-ref.xml new file mode 100644 index 00000000000..d0757977251 --- /dev/null +++ b/mozilla/layout/reftests/bugs/355548-1-ref.xml @@ -0,0 +1,36 @@ + + +

+ Id + Id + Id + Id +

+ +

+ Id + Id +

+ +

+ Id + Id + Id +

+

+ Id + Id + Id +

+

+ Id + Id + Id +

+

+ Id + Id + Id +

+ + diff --git a/mozilla/layout/reftests/bugs/355548-1.xml b/mozilla/layout/reftests/bugs/355548-1.xml new file mode 100644 index 00000000000..95449c1a791 --- /dev/null +++ b/mozilla/layout/reftests/bugs/355548-1.xml @@ -0,0 +1,36 @@ + + +

+ Id + Id + Id + Id +

+ +

+ Id + Id +

+ +

+ Id + Id + Id +

+

+ Id + Id + Id +

+

+ Id + Id + Id +

+

+ Id + Id + Id +

+ + diff --git a/mozilla/layout/reftests/bugs/355548-2-ref.xml b/mozilla/layout/reftests/bugs/355548-2-ref.xml new file mode 100644 index 00000000000..dce6d1457f7 --- /dev/null +++ b/mozilla/layout/reftests/bugs/355548-2-ref.xml @@ -0,0 +1,25 @@ + + +

+ Id + Id + Id +

+ +

+ Id +

+ +

+ Id + Id + Id +

+

+ Id + Id + Id + Id +

+ + diff --git a/mozilla/layout/reftests/bugs/355548-2.xml b/mozilla/layout/reftests/bugs/355548-2.xml new file mode 100644 index 00000000000..6bc567a40c0 --- /dev/null +++ b/mozilla/layout/reftests/bugs/355548-2.xml @@ -0,0 +1,38 @@ + + + +

+ Id + + Id + + Id +

+ +

+ + Id +

+ +

+ + Id + + Id + Id +

+ +

+ + Id + + Id + + Id + + Id +

+ + + diff --git a/mozilla/layout/reftests/bugs/355548-3-ref.xml b/mozilla/layout/reftests/bugs/355548-3-ref.xml new file mode 100644 index 00000000000..d4f2e9fb085 --- /dev/null +++ b/mozilla/layout/reftests/bugs/355548-3-ref.xml @@ -0,0 +1,67 @@ + + +

+ Id +

+ +

+ Id + Id + Id + Id +

+ +

+ Id + Id + Id + Id + Id + Id +

+ +

+ Id + Id +

+ +

+ Id + Id + Id + Id +

+ +

+ Id + Id +

+ +

+ Id + Id + Id + Id +

+ +

+ Id + Id + Id + Id + Id + Id +

+ +

+ Id + Id + Id + Id + Id + Id + Id +

+ + + diff --git a/mozilla/layout/reftests/bugs/355548-3.xml b/mozilla/layout/reftests/bugs/355548-3.xml new file mode 100644 index 00000000000..b1a6958b48c --- /dev/null +++ b/mozilla/layout/reftests/bugs/355548-3.xml @@ -0,0 +1,78 @@ + + + +

+ + Id +

+ +

+ Id + Id + + Id + + Id +

+ +

+ Id + Id + Id + + Id + Id + Id +

+ +

+ Id + Id +

+ +

+ Id + Id + + Id + + Id +

+ +

+ Id + Id +

+ +

+ Id + Id + + Id + + Id +

+ +

+ + Id + Id + Id + Id + Id + Id +

+ +

+ + Id + Id + Id + Id + Id + Id + Id +

+ + + diff --git a/mozilla/layout/reftests/bugs/355548-4-ref.xml b/mozilla/layout/reftests/bugs/355548-4-ref.xml new file mode 100644 index 00000000000..4424c25d3d8 --- /dev/null +++ b/mozilla/layout/reftests/bugs/355548-4-ref.xml @@ -0,0 +1,11 @@ + + + + + +

Hello

+Id + + diff --git a/mozilla/layout/reftests/bugs/355548-4.xml b/mozilla/layout/reftests/bugs/355548-4.xml new file mode 100644 index 00000000000..5a73aff01cf --- /dev/null +++ b/mozilla/layout/reftests/bugs/355548-4.xml @@ -0,0 +1,41 @@ + + + + + + +

Hello

+ + diff --git a/mozilla/layout/reftests/bugs/355548-5-ref.xml b/mozilla/layout/reftests/bugs/355548-5-ref.xml new file mode 100644 index 00000000000..fb71442ab4d --- /dev/null +++ b/mozilla/layout/reftests/bugs/355548-5-ref.xml @@ -0,0 +1,7 @@ + + +

+ Id +

+ + diff --git a/mozilla/layout/reftests/bugs/355548-5.xml b/mozilla/layout/reftests/bugs/355548-5.xml new file mode 100644 index 00000000000..30dbbc88315 --- /dev/null +++ b/mozilla/layout/reftests/bugs/355548-5.xml @@ -0,0 +1,7 @@ + + +

+ Id +

+ + diff --git a/mozilla/layout/reftests/bugs/reftest.list b/mozilla/layout/reftests/bugs/reftest.list index 7175ad58233..f4738c9b969 100644 --- a/mozilla/layout/reftests/bugs/reftest.list +++ b/mozilla/layout/reftests/bugs/reftest.list @@ -304,6 +304,11 @@ fails == 352980-1h.html 352980-1-ref.html == 352980-3d.html 352980-3-ref.html == 352980-3e.html 352980-3-ref.html == 352980-3f.html 352980-3-ref.html +== 355548-1.xml 355548-1-ref.xml +== 355548-2.xml 355548-2-ref.xml +== 355548-3.xml 355548-3-ref.xml +== 355548-4.xml 355548-4-ref.xml +== 355548-5.xml 355548-5-ref.xml == 359903-1.html 359903-1-ref.html == 359869-1.html 359869-1-ref.html == 359903-2.html 359903-2-ref.html diff --git a/mozilla/layout/style/nsCSSParser.cpp b/mozilla/layout/style/nsCSSParser.cpp index 0eb01ce79d1..7426e6f6560 100644 --- a/mozilla/layout/style/nsCSSParser.cpp +++ b/mozilla/layout/style/nsCSSParser.cpp @@ -4618,6 +4618,10 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode, case eCSSProperty_border_left_width_rtl_source: case eCSSProperty_border_right_width_ltr_source: case eCSSProperty_border_right_width_rtl_source: +#ifdef MOZ_MATHML + case eCSSProperty_script_size_multiplier: + case eCSSProperty_script_min_size: +#endif NS_ERROR("not currently parsed here"); return PR_FALSE; @@ -4933,6 +4937,16 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode, return ParseVariant(aErrorCode, aValue, VARIANT_HK, nsCSSProps::kPositionKTable); case eCSSProperty_richness: return ParseVariant(aErrorCode, aValue, VARIANT_HN, nsnull); +#ifdef MOZ_MATHML + // script-level can take Integer or Number values, but only Integer ("relative") + // values can be specified in a style sheet. Also we only allow this property + // when unsafe rules are enabled, because otherwise it could interfere + // with rulenode optimizations if used in a non-MathML-enabled document. + case eCSSProperty_script_level: + if (!mUnsafeRulesEnabled) + return PR_FALSE; + return ParseVariant(aErrorCode, aValue, VARIANT_HI, nsnull); +#endif case eCSSProperty_speak: return ParseVariant(aErrorCode, aValue, VARIANT_HMK | VARIANT_NONE, nsCSSProps::kSpeakKTable); diff --git a/mozilla/layout/style/nsCSSPropList.h b/mozilla/layout/style/nsCSSPropList.h index fa7ffe55e97..6967f9d889c 100644 --- a/mozilla/layout/style/nsCSSPropList.h +++ b/mozilla/layout/style/nsCSSPropList.h @@ -517,6 +517,14 @@ CSS_PROP_XUL(-moz-box-orient, box_orient, MozBoxOrient, XUL, mBoxOrient, eCSSTyp CSS_PROP_XUL(-moz-box-pack, box_pack, MozBoxPack, XUL, mBoxPack, eCSSType_Value, kBoxPackKTable) // XXX bug 3935 CSS_PROP_XUL(-moz-box-ordinal-group, box_ordinal_group, MozBoxOrdinalGroup, XUL, mBoxOrdinal, eCSSType_Value, nsnull) +#ifdef MOZ_MATHML +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_FONT(-moz-script-level, script_level, ScriptLevel, Font, mScriptLevel, eCSSType_Value, nsnull) +CSS_PROP_FONT(-moz-script-size-multiplier, script_size_multiplier, ScriptSizeMultiplier, Font, mScriptSizeMultiplier, eCSSType_Value, nsnull) +CSS_PROP_FONT(-moz-script-min-size, script_min_size, ScriptMinSize, Font, mScriptMinSize, eCSSType_Value, nsnull) +#endif +#endif + #ifdef MOZ_SVG // XXX treat SVG's CSS Properties as internal for now. // Do we want to create an nsIDOMSVGCSS2Properties interface? diff --git a/mozilla/layout/style/nsCSSPseudoClassList.h b/mozilla/layout/style/nsCSSPseudoClassList.h index d29a673a037..a940ec4529a 100644 --- a/mozilla/layout/style/nsCSSPseudoClassList.h +++ b/mozilla/layout/style/nsCSSPseudoClassList.h @@ -94,6 +94,10 @@ CSS_PSEUDO_CLASS(mozIsHTML, ":-moz-is-html") // Matches anything when the specified look-and-feel metric is set CSS_PSEUDO_CLASS(mozSystemMetric, ":-moz-system-metric") +#ifdef MOZ_MATHML +CSS_PSEUDO_CLASS(mozMathIncrementScriptLevel, ":-moz-math-increment-script-level") +#endif + // CSS 3 UI // http://www.w3.org/TR/2004/CR-css3-ui-20040511/#pseudo-classes CSS_PSEUDO_CLASS(required, ":required") diff --git a/mozilla/layout/style/nsCSSRuleProcessor.cpp b/mozilla/layout/style/nsCSSRuleProcessor.cpp index 318ebb97415..9aa02421810 100644 --- a/mozilla/layout/style/nsCSSRuleProcessor.cpp +++ b/mozilla/layout/style/nsCSSRuleProcessor.cpp @@ -1335,6 +1335,11 @@ static PRBool SelectorMatches(RuleProcessorData &data, result = data.mIsHTMLContent && data.mContent->GetNameSpaceID() == kNameSpaceID_None; } +#ifdef MOZ_MATHML + else if (nsCSSPseudoClasses::mozMathIncrementScriptLevel == pseudoClass->mAtom) { + stateToCheck = NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL; + } +#endif else { NS_ERROR("CSS parser parsed a pseudo-class that we do not handle"); result = PR_FALSE; // unknown pseudo class @@ -1918,6 +1923,9 @@ PRBool IsStateSelector(nsCSSSelector& aSelector) (pseudoClass->mAtom == nsCSSPseudoClasses::outOfRange) || (pseudoClass->mAtom == nsCSSPseudoClasses::mozReadOnly) || (pseudoClass->mAtom == nsCSSPseudoClasses::mozReadWrite) || +#ifdef MOZ_MATHML + (pseudoClass->mAtom == nsCSSPseudoClasses::mozMathIncrementScriptLevel) || +#endif (pseudoClass->mAtom == nsCSSPseudoClasses::defaultPseudo)) { return PR_TRUE; } diff --git a/mozilla/layout/style/nsCSSStruct.h b/mozilla/layout/style/nsCSSStruct.h index 26fccbbad19..39f16a7842b 100644 --- a/mozilla/layout/style/nsCSSStruct.h +++ b/mozilla/layout/style/nsCSSStruct.h @@ -210,6 +210,12 @@ struct nsCSSFont : public nsCSSStruct { nsCSSValue mSizeAdjust; // NEW nsCSSValue mStretch; // NEW +#ifdef MOZ_MATHML + nsCSSValue mScriptLevel; // Integer values mean "relative", Number values mean "absolute" + nsCSSValue mScriptSizeMultiplier; + nsCSSValue mScriptMinSize; +#endif + private: nsCSSFont(const nsCSSFont& aOther); // NOT IMPLEMENTED }; diff --git a/mozilla/layout/style/nsRuleNode.cpp b/mozilla/layout/style/nsRuleNode.cpp index 75de635074e..2f57d3341c3 100644 --- a/mozilla/layout/style/nsRuleNode.cpp +++ b/mozilla/layout/style/nsRuleNode.cpp @@ -185,7 +185,7 @@ static void EnsureBlockDisplay(PRUint8& display) } // XXX This should really be done in the CSS parser. -nsString& Unquote(nsString& aString) +static nsString& Unquote(nsString& aString) { PRUnichar start = aString.First(); PRUnichar end = aString.Last(); @@ -200,13 +200,17 @@ nsString& Unquote(nsString& aString) return aString; } -nscoord CalcLength(const nsCSSValue& aValue, - const nsFont* aFont, - nsStyleContext* aStyleContext, - nsPresContext* aPresContext, - PRBool& aInherited) +static nscoord CalcLengthWith(const nsCSSValue& aValue, + nscoord aFontSize, + const nsStyleFont* aStyleFont, + nsStyleContext* aStyleContext, + nsPresContext* aPresContext, + PRBool& aInherited) { NS_ASSERTION(aValue.IsLengthUnit(), "not a length unit"); + NS_ASSERTION(aStyleFont || aStyleContext, "Must have style data"); + NS_ASSERTION(aPresContext, "Must have prescontext"); + if (aValue.IsFixedLengthUnit()) { return aPresContext->TwipsToAppUnits(aValue.GetLengthTwips()); } @@ -216,31 +220,35 @@ nscoord CalcLength(const nsCSSValue& aValue, } // Common code for all units other than pixels: aInherited = PR_TRUE; - const nsFont* font; - if (aStyleContext) { - font = &aStyleContext->GetStyleFont()->mFont; - } else { - font = aFont; + if (!aStyleFont) { + aStyleFont = aStyleContext->GetStyleFont(); + } + if (aFontSize == -1) { + // XXX Should this be aStyleFont->mSize instead to avoid taking minfontsize + // prefs into account? + aFontSize = aStyleFont->mFont.size; } switch (unit) { case eCSSUnit_EM: case eCSSUnit_Char: { - return NSToCoordRound(aValue.GetFloatValue() * (float)font->size); + return NSToCoordRound(aValue.GetFloatValue() * float(aFontSize)); // XXX scale against font metrics height instead? } case eCSSUnit_EN: { - return NSToCoordRound((aValue.GetFloatValue() * (float)font->size) / 2.0f); + return NSToCoordRound((aValue.GetFloatValue() * float(aFontSize)) / 2.0f); } case eCSSUnit_XHeight: { - nsCOMPtr fm = aPresContext->GetMetricsFor(*font); + nsFont font = aStyleFont->mFont; + font.size = aFontSize; + nsCOMPtr fm = aPresContext->GetMetricsFor(font); nscoord xHeight; fm->GetXHeight(xHeight); - return NSToCoordRound(aValue.GetFloatValue() * (float)xHeight); + return NSToCoordRound(aValue.GetFloatValue() * float(xHeight)); } case eCSSUnit_CapHeight: { NS_NOTYETIMPLEMENTED("cap height unit"); - nscoord capHeight = ((font->size / 3) * 2); // XXX HACK! - return NSToCoordRound(aValue.GetFloatValue() * (float)capHeight); + nscoord capHeight = ((aFontSize / 3) * 2); // XXX HACK! + return NSToCoordRound(aValue.GetFloatValue() * float(capHeight)); } default: NS_NOTREACHED("unexpected unit"); @@ -249,6 +257,16 @@ nscoord CalcLength(const nsCSSValue& aValue, return 0; } +static nscoord CalcLength(const nsCSSValue& aValue, + nsStyleContext* aStyleContext, + nsPresContext* aPresContext, + PRBool& aInherited) +{ + NS_ASSERTION(aStyleContext, "Must have style data"); + + return CalcLengthWith(aValue, -1, nsnull, aStyleContext, aPresContext, aInherited); +} + #define SETCOORD_NORMAL 0x01 // N #define SETCOORD_AUTO 0x02 // A #define SETCOORD_INHERIT 0x04 // H @@ -294,8 +312,8 @@ static PRBool SetCoord(const nsCSSValue& aValue, nsStyleCoord& aCoord, } else if (((aMask & SETCOORD_LENGTH) != 0) && aValue.IsLengthUnit()) { - aCoord.SetCoordValue(CalcLength(aValue, nsnull, aStyleContext, aPresContext, aInherited)); - } + aCoord.SetCoordValue(CalcLength(aValue, aStyleContext, aPresContext, aInherited)); + } else if (((aMask & SETCOORD_PERCENT) != 0) && (aValue.GetUnit() == eCSSUnit_Percent)) { aCoord.SetPercentValue(aValue.GetPercentValue()); @@ -676,6 +694,9 @@ CheckFontCallback(const nsRuleDataStruct& aData, (size.GetUnit() == eCSSUnit_Enumerated && (size.GetIntValue() == NS_STYLE_FONT_SIZE_SMALLER || size.GetIntValue() == NS_STYLE_FONT_SIZE_LARGER)) || +#ifdef MOZ_MATHML + fontData.mScriptLevel.GetUnit() == eCSSUnit_Integer || +#endif (weight.GetUnit() == eCSSUnit_Enumerated && (weight.GetIntValue() == NS_STYLE_FONT_WEIGHT_BOLDER || weight.GetIntValue() == NS_STYLE_FONT_WEIGHT_LIGHTER))) { @@ -949,6 +970,16 @@ QuotesAtOffset(const nsRuleDataStruct& aRuleDataStruct, size_t aOffset) (reinterpret_cast(&aRuleDataStruct) + aOffset); } +#if defined(MOZ_MATHML) && defined(DEBUG) +static PRBool +AreAllMathMLPropertiesUndefined(const nsCSSFont& aRuleData) +{ + return aRuleData.mScriptLevel.GetUnit() == eCSSUnit_Null && + aRuleData.mScriptSizeMultiplier.GetUnit() == eCSSUnit_Null && + aRuleData.mScriptMinSize.GetUnit() == eCSSUnit_Null; +} +#endif + inline nsRuleNode::RuleDetail nsRuleNode::CheckSpecifiedProperties(const nsStyleStructID aSID, const nsRuleDataStruct& aRuleDataStruct) @@ -1038,6 +1069,13 @@ nsRuleNode::CheckSpecifiedProperties(const nsStyleStructID aSID, aSID, total, specified, inherited); #endif +#ifdef MOZ_MATHML + NS_ASSERTION(aSID != eStyleStruct_Font || + mPresContext->Document()->GetMathMLEnabled() || + AreAllMathMLPropertiesUndefined(static_cast(aRuleDataStruct)), + "MathML style property was defined even though MathML is disabled"); +#endif + /* * Return the most specific information we can: prefer None or Full * over Partial, and Reset or Inherited over Mixed, since we can @@ -1046,7 +1084,18 @@ nsRuleNode::CheckSpecifiedProperties(const nsStyleStructID aSID, nsRuleNode::RuleDetail result; if (inherited == total) result = eRuleFullInherited; - else if (specified == total) { + else if (specified == total +#ifdef MOZ_MATHML + // MathML defines 3 properties in Font that will never be set when + // MathML is not in use. Therefore if all but three + // properties have been set, and MathML is not enabled, we can treat + // this as fully specified. Code in nsMathMLElementFactory will + // rebuild the rule tree and style data when MathML is first enabled + // (see nsMathMLElement::BindToTree). + || (aSID == eStyleStruct_Font && specified + 3 == total && + !mPresContext->Document()->GetMathMLEnabled()) +#endif + ) { if (inherited == 0) result = eRuleFullReset; else @@ -1885,13 +1934,201 @@ nsRuleNode::AdjustLogicalBoxProp(nsStyleContext* aContext, } \ \ return data_; - + +#ifdef MOZ_MATHML +// This function figures out how much scaling should be suppressed to +// satisfy scriptminsize. This is our attempt to implement +// http://www.w3.org/TR/MathML2/chapter3.html#id.3.3.4.2.2 +// This is called after mScriptLevel, mScriptMinSize and mScriptSizeMultiplier +// have been set in aFont. +// +// Here are the invariants we enforce: +// 1) A decrease in size must not reduce the size below minscriptsize. +// 2) An increase in size must not increase the size above the size we would +// have if minscriptsize had not been applied anywhere. +// 3) The scriptlevel-induced size change must between 1.0 and the parent's +// scriptsizemultiplier^(new script level - old script level), as close to the +// latter as possible subject to constraints 1 and 2. +static nscoord +ComputeScriptLevelSize(const nsStyleFont* aFont, const nsStyleFont* aParentFont, + nsPresContext* aPresContext, nscoord* aUnconstrainedSize) +{ + PRInt32 scriptLevelChange = + aFont->mScriptLevel - aParentFont->mScriptLevel; + if (scriptLevelChange == 0) { + *aUnconstrainedSize = aParentFont->mScriptUnconstrainedSize; + // Constraint #3 says that we cannot change size, and #1 and #2 are always + // satisfied with no change. It's important this be fast because it covers + // all non-MathML content. + return aParentFont->mSize; + } + + // Compute actual value of minScriptSize + nscoord minScriptSize = + nsStyleFont::ZoomText(aPresContext, aParentFont->mScriptMinSize); + + double scriptLevelScale = + pow(aParentFont->mScriptSizeMultiplier, scriptLevelChange); + // Compute the size we would have had if minscriptsize had never been applied + *aUnconstrainedSize = + NSToCoordRound(aParentFont->mScriptUnconstrainedSize*scriptLevelScale); + // Compute the size we could get via scriptlevel change + nscoord scriptLevelSize = + NSToCoordRound(aParentFont->mSize*scriptLevelScale); + if (scriptLevelScale <= 1.0) { + if (aParentFont->mSize <= minScriptSize) { + // We can't decrease the font size at all, so just stick to no change + // (authors are allowed to explicitly set the font size smaller than + // minscriptsize) + return aParentFont->mSize; + } + // We can decrease, so apply constraint #1 + return PR_MAX(minScriptSize, scriptLevelSize); + } else { + // scriptminsize can only make sizes larger than the unconstrained size + NS_ASSERTION(*aUnconstrainedSize <= scriptLevelSize, "How can this ever happen?"); + // Apply constraint #2 + return PR_MIN(scriptLevelSize, PR_MAX(*aUnconstrainedSize, minScriptSize)); + } +} +#endif + +/* static */ void +nsRuleNode::SetFontSize(nsPresContext* aPresContext, + const nsRuleDataFont& aFontData, + const nsStyleFont* aFont, + const nsStyleFont* aParentFont, + nscoord* aSize, + const nsFont& aSystemFont, + nscoord aParentSize, + nscoord aScriptLevelAdjustedParentSize, + PRBool aUsedStartStruct, + PRBool& aInherited) +{ + PRBool zoom = PR_FALSE; + PRInt32 baseSize = (PRInt32) aPresContext-> + GetDefaultFont(aFont->mFlags & NS_STYLE_FONT_FACE_MASK)->size; + if (eCSSUnit_Enumerated == aFontData.mSize.GetUnit()) { + PRInt32 value = aFontData.mSize.GetIntValue(); + PRInt32 scaler = aPresContext->FontScaler(); + float scaleFactor = nsStyleUtil::GetScalingFactor(scaler); + + zoom = PR_TRUE; + if ((NS_STYLE_FONT_SIZE_XXSMALL <= value) && + (value <= NS_STYLE_FONT_SIZE_XXLARGE)) { + *aSize = nsStyleUtil::CalcFontPointSize(value, baseSize, + scaleFactor, aPresContext, eFontSize_CSS); + } + else if (NS_STYLE_FONT_SIZE_XXXLARGE == value) { + // is not specified in CSS, so we don't use eFontSize_CSS. + *aSize = nsStyleUtil::CalcFontPointSize(value, baseSize, + scaleFactor, aPresContext); + } + else if (NS_STYLE_FONT_SIZE_LARGER == value || + NS_STYLE_FONT_SIZE_SMALLER == value) { + aInherited = PR_TRUE; + + // Un-zoom so we use the tables correctly. We'll then rezoom due + // to the |zoom = PR_TRUE| above. + // Note that relative units here use the parent's size unadjusted + // for scriptlevel changes. A scriptlevel change between us and the parent + // is simply ignored. + nscoord parentSize = + nsStyleFont::UnZoomText(aPresContext, aParentSize); + + if (NS_STYLE_FONT_SIZE_LARGER == value) { + *aSize = nsStyleUtil::FindNextLargerFontSize(parentSize, + baseSize, scaleFactor, aPresContext, eFontSize_CSS); + NS_ASSERTION(*aSize > parentSize, + "FindNextLargerFontSize failed"); + } + else { + *aSize = nsStyleUtil::FindNextSmallerFontSize(parentSize, + baseSize, scaleFactor, aPresContext, eFontSize_CSS); + NS_ASSERTION(*aSize < parentSize || + parentSize <= nsPresContext::CSSPixelsToAppUnits(1), + "FindNextSmallerFontSize failed"); + } + } else { + NS_NOTREACHED("unexpected value"); + } + } + else if (aFontData.mSize.IsLengthUnit()) { + // Note that font-based length units use the parent's size unadjusted + // for scriptlevel changes. A scriptlevel change between us and the parent + // is simply ignored. + *aSize = CalcLengthWith(aFontData.mSize, aParentSize, aParentFont, nsnull, + aPresContext, aInherited); + zoom = aFontData.mSize.IsFixedLengthUnit() || + aFontData.mSize.GetUnit() == eCSSUnit_Pixel; + } + else if (eCSSUnit_Percent == aFontData.mSize.GetUnit()) { + aInherited = PR_TRUE; + // Note that % units use the parent's size unadjusted for scriptlevel + // changes. A scriptlevel change between us and the parent is simply + // ignored. + *aSize = NSToCoordRound(aParentSize * + aFontData.mSize.GetPercentValue()); + zoom = PR_FALSE; + } + else if (eCSSUnit_System_Font == aFontData.mSize.GetUnit()) { + // this becomes our cascading size + *aSize = aSystemFont.size; + zoom = PR_TRUE; + } + else if (eCSSUnit_Inherit == aFontData.mSize.GetUnit()) { + aInherited = PR_TRUE; + // We apply scriptlevel change for this case, because the default is + // to inherit and we don't want explicit "inherit" to differ from the + // default. + *aSize = aScriptLevelAdjustedParentSize; + zoom = PR_FALSE; + } + else if (eCSSUnit_Initial == aFontData.mSize.GetUnit()) { + // The initial value is 'medium', which has magical sizing based on + // the generic font family, so do that here too. + *aSize = baseSize; + zoom = PR_TRUE; + } else { + NS_ASSERTION(eCSSUnit_Null == aFontData.mSize.GetUnit(), + "What kind of font-size value is this?"); +#ifdef MOZ_MATHML + // if aUsedStartStruct is true, then every single property in the + // font struct is being set all at once. This means scriptlevel is not + // going to have any influence on the font size; there is no need to + // do anything here. + if (!aUsedStartStruct && aParentSize != aScriptLevelAdjustedParentSize) { + // There was no rule affecting the size but the size has been + // affected by the parent's size via scriptlevel change. So treat + // this as inherited. + aInherited = PR_TRUE; + *aSize = aScriptLevelAdjustedParentSize; + } +#endif + } + + // We want to zoom the cascaded size so that em-based measurements, + // line-heights, etc., work. + if (zoom) { + *aSize = nsStyleFont::ZoomText(aPresContext, *aSize); + } +} + +static PRInt8 ClampTo8Bit(PRInt32 aValue) { + if (aValue < -128) + return -128; + if (aValue > 127) + return 127; + return PRInt8(aValue); +} + /* static */ void nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext, nscoord aMinFontSize, PRUint8 aGenericFontID, const nsRuleDataFont& aFontData, const nsStyleFont* aParentFont, - nsStyleFont* aFont, PRBool& aInherited) + nsStyleFont* aFont, PRBool aUsedStartStruct, + PRBool& aInherited) { const nsFont* defaultVariableFont = aPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID); @@ -2082,85 +2319,79 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext, aFont->mFont.weight = defaultVariableFont->weight; } +#ifdef MOZ_MATHML + // Compute scriptlevel, scriptminsize and scriptsizemultiplier now so + // they're available for font-size computation. + + // -moz-script-min-size: length + if (aFontData.mScriptMinSize.IsLengthUnit()) { + aFont->mScriptMinSize = + CalcLength(aFontData.mScriptMinSize, aContext, aPresContext, aInherited); + } + + // -moz-script-size-multiplier: factor, inherit + if (eCSSUnit_Number == aFontData.mScriptSizeMultiplier.GetUnit()) { + aFont->mScriptSizeMultiplier = aFontData.mScriptSizeMultiplier.GetFloatValue(); + NS_ASSERTION(aFont->mScriptSizeMultiplier >= 0.0f, "Cannot have negative script size multiplier"); + } + else if (eCSSUnit_Inherit == aFontData.mScriptSizeMultiplier.GetUnit()) { + aInherited = PR_TRUE; + aFont->mScriptSizeMultiplier = aParentFont->mScriptSizeMultiplier; + } + else if (eCSSUnit_Initial == aFontData.mScriptSizeMultiplier.GetUnit()) { + aFont->mScriptSizeMultiplier = NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER; + } + + // -moz-script-level: integer, number, inherit + if (eCSSUnit_Integer == aFontData.mScriptLevel.GetUnit()) { + // "relative" + aFont->mScriptLevel = ClampTo8Bit(aParentFont->mScriptLevel + aFontData.mScriptLevel.GetIntValue()); + } + else if (eCSSUnit_Number == aFontData.mScriptLevel.GetUnit()) { + // "absolute" + aFont->mScriptLevel = ClampTo8Bit(PRInt32(aFontData.mScriptLevel.GetFloatValue())); + } + else if (eCSSUnit_Inherit == aFontData.mScriptSizeMultiplier.GetUnit()) { + aInherited = PR_TRUE; + aFont->mScriptLevel = aParentFont->mScriptLevel; + } + else if (eCSSUnit_Initial == aFontData.mScriptSizeMultiplier.GetUnit()) { + aFont->mScriptLevel = 0; + } +#endif + // font-size: enum, length, percent, inherit - PRBool zoom = PR_FALSE; - PRInt32 baseSize = (PRInt32) aPresContext-> - GetDefaultFont(aFont->mFlags & NS_STYLE_FONT_FACE_MASK)->size; - if (eCSSUnit_Enumerated == aFontData.mSize.GetUnit()) { - PRInt32 value = aFontData.mSize.GetIntValue(); - PRInt32 scaler = aPresContext->FontScaler(); - float scaleFactor = nsStyleUtil::GetScalingFactor(scaler); - - zoom = PR_TRUE; - if ((NS_STYLE_FONT_SIZE_XXSMALL <= value) && - (value <= NS_STYLE_FONT_SIZE_XXLARGE)) { - aFont->mSize = nsStyleUtil::CalcFontPointSize(value, baseSize, - scaleFactor, aPresContext, eFontSize_CSS); - } - else if (NS_STYLE_FONT_SIZE_XXXLARGE == value) { - // is not specified in CSS, so we don't use eFontSize_CSS. - aFont->mSize = nsStyleUtil::CalcFontPointSize(value, baseSize, - scaleFactor, aPresContext); - } - else if (NS_STYLE_FONT_SIZE_LARGER == value || - NS_STYLE_FONT_SIZE_SMALLER == value) { - - aInherited = PR_TRUE; - - // Un-zoom so we use the tables correctly. We'll then rezoom due - // to the |zoom = PR_TRUE| above. - nscoord parentSize = - nsStyleFont::UnZoomText(aPresContext, aParentFont->mSize); - - if (NS_STYLE_FONT_SIZE_LARGER == value) { - aFont->mSize = nsStyleUtil::FindNextLargerFontSize(parentSize, - baseSize, scaleFactor, aPresContext, eFontSize_CSS); - NS_ASSERTION(aFont->mSize > parentSize, - "FindNextLargerFontSize failed"); - } - else { - aFont->mSize = nsStyleUtil::FindNextSmallerFontSize(parentSize, - baseSize, scaleFactor, aPresContext, eFontSize_CSS); - NS_ASSERTION(aFont->mSize < parentSize || - parentSize <= nsPresContext::CSSPixelsToAppUnits(1), - "FindNextSmallerFontSize failed"); - } - } else { - NS_NOTREACHED("unexpected value"); - } + nscoord scriptLevelAdjustedParentSize = aParentFont->mSize; +#ifdef MOZ_MATHML + nscoord scriptLevelAdjustedUnconstrainedParentSize; + scriptLevelAdjustedParentSize = + ComputeScriptLevelSize(aFont, aParentFont, aPresContext, + &scriptLevelAdjustedUnconstrainedParentSize); + NS_ASSERTION(!aUsedStartStruct || aFont->mScriptUnconstrainedSize == aFont->mSize, + "If we have a start struct, we should have reset everything coming in here"); +#endif + SetFontSize(aPresContext, aFontData, aFont, aParentFont, &aFont->mSize, + systemFont, aParentFont->mSize, scriptLevelAdjustedParentSize, + aUsedStartStruct, aInherited); +#ifdef MOZ_MATHML + if (aParentFont->mSize == aParentFont->mScriptUnconstrainedSize && + scriptLevelAdjustedParentSize == scriptLevelAdjustedUnconstrainedParentSize) { + // Fast path: we have not been affected by scriptminsize so we don't + // need to call SetFontSize again to compute the + // scriptminsize-unconstrained size. This is OK even if we have a + // start struct, because if we have a start struct then 'font-size' + // was specified and so scriptminsize has no effect. + aFont->mScriptUnconstrainedSize = aFont->mSize; + } else { + SetFontSize(aPresContext, aFontData, aFont, aParentFont, + &aFont->mScriptUnconstrainedSize, systemFont, + aParentFont->mScriptUnconstrainedSize, + scriptLevelAdjustedUnconstrainedParentSize, + aUsedStartStruct, aInherited); } - else if (aFontData.mSize.IsLengthUnit()) { - aFont->mSize = CalcLength(aFontData.mSize, &aParentFont->mFont, nsnull, aPresContext, aInherited); - zoom = aFontData.mSize.IsFixedLengthUnit() || - aFontData.mSize.GetUnit() == eCSSUnit_Pixel; - } - else if (eCSSUnit_Percent == aFontData.mSize.GetUnit()) { - aInherited = PR_TRUE; - aFont->mSize = NSToCoordRound(float(aParentFont->mSize) * - aFontData.mSize.GetPercentValue()); - zoom = PR_FALSE; - } - else if (eCSSUnit_System_Font == aFontData.mSize.GetUnit()) { - // this becomes our cascading size - aFont->mSize = systemFont.size; - zoom = PR_TRUE; - } - else if (eCSSUnit_Inherit == aFontData.mSize.GetUnit()) { - aInherited = PR_TRUE; - aFont->mSize = aParentFont->mSize; - zoom = PR_FALSE; - } - else if (eCSSUnit_Initial == aFontData.mSize.GetUnit()) { - // The initial value is 'medium', which has magical sizing based on - // the generic font family, so do that here too. - aFont->mSize = baseSize; - zoom = PR_TRUE; - } - - // We want to zoom the cascaded size so that em-based measurements, - // line-heights, etc., work. - if (zoom) - aFont->mSize = nsStyleFont::ZoomText(aPresContext, aFont->mSize); + NS_ASSERTION(aFont->mScriptUnconstrainedSize <= aFont->mSize, + "scriptminsize should never be making things bigger"); +#endif // enforce the user' specified minimum font-size on the value that we expose aFont->mFont.size = PR_MAX(aFont->mSize, aMinFontSize); @@ -2213,18 +2444,12 @@ nsRuleNode::SetGenericFont(nsPresContext* aPresContext, // we will start with the default generic font from the presentation // context. Otherwise we start with the higher context. const nsFont* defaultFont = aPresContext->GetDefaultFont(aGenericFontID); - nsStyleFont parentFont(*defaultFont); - parentFont.mSize = parentFont.mFont.size - = nsStyleFont::ZoomText(aPresContext, parentFont.mSize); + nsStyleFont parentFont(*defaultFont, aPresContext); if (higherContext) { const nsStyleFont* tmpFont = higherContext->GetStyleFont(); - parentFont.mFlags = tmpFont->mFlags; - parentFont.mFont = tmpFont->mFont; - parentFont.mSize = tmpFont->mSize; + parentFont = *tmpFont; } - aFont->mFlags = parentFont.mFlags; - aFont->mFont = parentFont.mFont; - aFont->mSize = parentFont.mSize; + *aFont = parentFont; PRBool dummy; PRUint32 fontBit = nsCachedStyleData::GetBitForSID(eStyleStruct_Font); @@ -2261,16 +2486,15 @@ nsRuleNode::SetGenericFont(nsPresContext* aPresContext, fontData.mFamily.Reset(); nsRuleNode::SetFont(aPresContext, context, aMinFontSize, - aGenericFontID, fontData, &parentFont, aFont, dummy); + aGenericFontID, fontData, &parentFont, aFont, + PR_FALSE, dummy); // XXX Not sure if we need to do this here // If we have a post-resolve callback, handle that now. if (ruleData.mPostResolveCallback) (ruleData.mPostResolveCallback)((nsStyleStruct*)aFont, &ruleData); - parentFont.mFlags = aFont->mFlags; - parentFont.mFont = aFont->mFont; - parentFont.mSize = aFont->mSize; + parentFont = *aFont; } } @@ -2308,7 +2532,7 @@ nsRuleNode::ComputeFontData(nsStyleStruct* aStartStruct, // using the 'font' shorthand). // See if there is a minimum font-size constraint to honor - nscoord minimumFontSize = + nscoord minimumFontSize = mPresContext->GetCachedIntPref(kPresContext_MinimumFontSize); if (minimumFontSize < 0) @@ -2366,7 +2590,8 @@ nsRuleNode::ComputeFontData(nsStyleStruct* aStartStruct, if (generic == kGenericFont_NONE) { // continue the normal processing nsRuleNode::SetFont(mPresContext, aContext, minimumFontSize, generic, - fontData, parentFont, font, inherited); + fontData, parentFont, font, + aStartStruct != nsnull, inherited); } else { // re-calculate the font as a generic font @@ -2943,7 +3168,7 @@ nsRuleNode::ComputeDisplayData(nsStyleStruct* aStartStruct, display->mClipFlags |= NS_STYLE_CLIP_TOP_AUTO; } else if (displayData.mClip.mTop.IsLengthUnit()) { - display->mClip.y = CalcLength(displayData.mClip.mTop, nsnull, aContext, mPresContext, inherited); + display->mClip.y = CalcLength(displayData.mClip.mTop, aContext, mPresContext, inherited); fullAuto = PR_FALSE; } if (eCSSUnit_Auto == displayData.mClip.mBottom.GetUnit()) { @@ -2954,7 +3179,7 @@ nsRuleNode::ComputeDisplayData(nsStyleStruct* aStartStruct, display->mClipFlags |= NS_STYLE_CLIP_BOTTOM_AUTO; } else if (displayData.mClip.mBottom.IsLengthUnit()) { - display->mClip.height = CalcLength(displayData.mClip.mBottom, nsnull, aContext, mPresContext, inherited) - + display->mClip.height = CalcLength(displayData.mClip.mBottom, aContext, mPresContext, inherited) - display->mClip.y; fullAuto = PR_FALSE; } @@ -2963,7 +3188,7 @@ nsRuleNode::ComputeDisplayData(nsStyleStruct* aStartStruct, display->mClipFlags |= NS_STYLE_CLIP_LEFT_AUTO; } else if (displayData.mClip.mLeft.IsLengthUnit()) { - display->mClip.x = CalcLength(displayData.mClip.mLeft, nsnull, aContext, mPresContext, inherited); + display->mClip.x = CalcLength(displayData.mClip.mLeft, aContext, mPresContext, inherited); fullAuto = PR_FALSE; } if (eCSSUnit_Auto == displayData.mClip.mRight.GetUnit()) { @@ -2974,7 +3199,7 @@ nsRuleNode::ComputeDisplayData(nsStyleStruct* aStartStruct, display->mClipFlags |= NS_STYLE_CLIP_RIGHT_AUTO; } else if (displayData.mClip.mRight.IsLengthUnit()) { - display->mClip.width = CalcLength(displayData.mClip.mRight, nsnull, aContext, mPresContext, inherited) - + display->mClip.width = CalcLength(displayData.mClip.mRight, aContext, mPresContext, inherited) - display->mClip.x; fullAuto = PR_FALSE; } @@ -3277,7 +3502,7 @@ nsRuleNode::ComputeBackgroundData(nsStyleStruct* aStartStruct, bg->mBackgroundFlags &= ~NS_STYLE_BG_X_POSITION_LENGTH; } else if (colorData.mBackPosition.mXValue.IsLengthUnit()) { - bg->mBackgroundXPosition.mCoord = CalcLength(colorData.mBackPosition.mXValue, nsnull, + bg->mBackgroundXPosition.mCoord = CalcLength(colorData.mBackPosition.mXValue, aContext, mPresContext, inherited); bg->mBackgroundFlags |= NS_STYLE_BG_X_POSITION_LENGTH; bg->mBackgroundFlags &= ~NS_STYLE_BG_X_POSITION_PERCENT; @@ -3316,7 +3541,7 @@ nsRuleNode::ComputeBackgroundData(nsStyleStruct* aStartStruct, bg->mBackgroundFlags &= ~NS_STYLE_BG_Y_POSITION_LENGTH; } else if (colorData.mBackPosition.mYValue.IsLengthUnit()) { - bg->mBackgroundYPosition.mCoord = CalcLength(colorData.mBackPosition.mYValue, nsnull, + bg->mBackgroundYPosition.mCoord = CalcLength(colorData.mBackPosition.mYValue, aContext, mPresContext, inherited); bg->mBackgroundFlags |= NS_STYLE_BG_Y_POSITION_LENGTH; bg->mBackgroundFlags &= ~NS_STYLE_BG_Y_POSITION_PERCENT; @@ -3779,23 +4004,23 @@ nsRuleNode::ComputeListData(nsStyleStruct* aStartStruct, if (eCSSUnit_Auto == listData.mImageRegion.mTop.GetUnit()) list->mImageRegion.y = 0; else if (listData.mImageRegion.mTop.IsLengthUnit()) - list->mImageRegion.y = CalcLength(listData.mImageRegion.mTop, nsnull, aContext, mPresContext, inherited); + list->mImageRegion.y = CalcLength(listData.mImageRegion.mTop, aContext, mPresContext, inherited); if (eCSSUnit_Auto == listData.mImageRegion.mBottom.GetUnit()) list->mImageRegion.height = 0; else if (listData.mImageRegion.mBottom.IsLengthUnit()) - list->mImageRegion.height = CalcLength(listData.mImageRegion.mBottom, nsnull, aContext, + list->mImageRegion.height = CalcLength(listData.mImageRegion.mBottom, aContext, mPresContext, inherited) - list->mImageRegion.y; if (eCSSUnit_Auto == listData.mImageRegion.mLeft.GetUnit()) list->mImageRegion.x = 0; else if (listData.mImageRegion.mLeft.IsLengthUnit()) - list->mImageRegion.x = CalcLength(listData.mImageRegion.mLeft, nsnull, aContext, mPresContext, inherited); + list->mImageRegion.x = CalcLength(listData.mImageRegion.mLeft, aContext, mPresContext, inherited); if (eCSSUnit_Auto == listData.mImageRegion.mRight.GetUnit()) list->mImageRegion.width = 0; else if (listData.mImageRegion.mRight.IsLengthUnit()) - list->mImageRegion.width = CalcLength(listData.mImageRegion.mRight, nsnull, aContext, mPresContext, inherited) - + list->mImageRegion.width = CalcLength(listData.mImageRegion.mRight, aContext, mPresContext, inherited) - list->mImageRegion.x; } diff --git a/mozilla/layout/style/nsRuleNode.h b/mozilla/layout/style/nsRuleNode.h index 377441df1d0..49ae15db9d8 100644 --- a/mozilla/layout/style/nsRuleNode.h +++ b/mozilla/layout/style/nsRuleNode.h @@ -600,13 +600,25 @@ protected: #endif // helpers for |ComputeFontData| that need access to |mNoneBits|: + static NS_HIDDEN_(void) SetFontSize(nsPresContext* aPresContext, + const nsRuleDataFont& aFontData, + const nsStyleFont* aFont, + const nsStyleFont* aParentFont, + nscoord* aSize, + const nsFont& aSystemFont, + nscoord aParentSize, + nscoord aScriptLevelAdjustedParentSize, + PRBool aUsedStartStruct, + PRBool& aInherited); + static NS_HIDDEN_(void) SetFont(nsPresContext* aPresContext, nsStyleContext* aContext, nscoord aMinFontSize, PRUint8 aGenericFontID, const nsRuleDataFont& aFontData, const nsStyleFont* aParentFont, - nsStyleFont* aFont, PRBool& aInherited); + nsStyleFont* aFont, + PRBool aStartStruct, PRBool& aInherited); static NS_HIDDEN_(void) SetGenericFont(nsPresContext* aPresContext, nsStyleContext* aContext, diff --git a/mozilla/layout/style/nsStyleStruct.cpp b/mozilla/layout/style/nsStyleStruct.cpp index 83b7868e9e1..3bc4ddf4bbc 100644 --- a/mozilla/layout/style/nsStyleStruct.cpp +++ b/mozilla/layout/style/nsStyleStruct.cpp @@ -106,33 +106,45 @@ static PRBool EqualImages(imgIRequest *aImage1, imgIRequest* aImage2) // -------------------- // nsStyleFont // -nsStyleFont::nsStyleFont() - : mFlags(NS_STYLE_FONT_DEFAULT), - mFont(nsnull, NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL, - NS_FONT_WEIGHT_NORMAL, NS_FONT_DECORATION_NONE, 0), - mSize(0) -{ } - -nsStyleFont::nsStyleFont(const nsFont& aFont) - : mFlags(NS_STYLE_FONT_DEFAULT), - mFont(aFont), - mSize(aFont.size) +nsStyleFont::nsStyleFont(const nsFont& aFont, nsPresContext *aPresContext) + : mFont(aFont), + mFlags(NS_STYLE_FONT_DEFAULT) { + mSize = mFont.size = nsStyleFont::ZoomText(aPresContext, mFont.size); +#ifdef MOZ_MATHML + mScriptUnconstrainedSize = mSize; + mScriptMinSize = aPresContext->TwipsToAppUnits( + NS_POINTS_TO_TWIPS(NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT)); + mScriptLevel = 0; + mScriptSizeMultiplier = NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER; +#endif } nsStyleFont::nsStyleFont(const nsStyleFont& aSrc) - : mFlags(aSrc.mFlags), - mFont(aSrc.mFont), - mSize(aSrc.mSize) + : mFont(aSrc.mFont) + , mSize(aSrc.mSize) + , mFlags(aSrc.mFlags) +#ifdef MOZ_MATHML + , mScriptLevel(aSrc.mScriptLevel) + , mScriptUnconstrainedSize(aSrc.mScriptUnconstrainedSize) + , mScriptSizeMultiplier(aSrc.mScriptSizeMultiplier) + , mScriptMinSize(aSrc.mScriptMinSize) +#endif { } - nsStyleFont::nsStyleFont(nsPresContext* aPresContext) - : mFlags(NS_STYLE_FONT_DEFAULT), - mFont(*(aPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID))) + : mFont(*(aPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID))), + mFlags(NS_STYLE_FONT_DEFAULT) { mSize = mFont.size = nsStyleFont::ZoomText(aPresContext, mFont.size); +#ifdef MOZ_MATHML + mScriptUnconstrainedSize = mSize; + mScriptMinSize = aPresContext->TwipsToAppUnits( + NS_POINTS_TO_TWIPS(NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT)); + mScriptLevel = 0; + mScriptSizeMultiplier = NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER; +#endif } void* diff --git a/mozilla/layout/style/nsStyleStruct.h b/mozilla/layout/style/nsStyleStruct.h index 0c2b9c92c9c..34e5ab53f38 100644 --- a/mozilla/layout/style/nsStyleStruct.h +++ b/mozilla/layout/style/nsStyleStruct.h @@ -89,8 +89,7 @@ struct nsStyleStruct { // The lifetime of these objects is managed by the presshell's arena. struct nsStyleFont : public nsStyleStruct { - nsStyleFont(void); - nsStyleFont(const nsFont& aFont); + nsStyleFont(const nsFont& aFont, nsPresContext *aPresContext); nsStyleFont(const nsStyleFont& aStyleFont); nsStyleFont(nsPresContext *aPresContext); ~nsStyleFont(void) {} @@ -103,16 +102,25 @@ struct nsStyleFont : public nsStyleStruct { static nscoord ZoomText(nsPresContext* aPresContext, nscoord aSize); static nscoord UnZoomText(nsPresContext* aPresContext, nscoord aSize); - + void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW; void Destroy(nsPresContext* aContext); - PRUint8 mFlags; // [inherited] See nsStyleConsts.h nsFont mFont; // [inherited] nscoord mSize; // [inherited] Our "computed size". Can be different from mFont.size // 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. + PRUint8 mFlags; // [inherited] See nsStyleConsts.h + +#ifdef MOZ_MATHML + // MathML scriptlevel support + PRInt8 mScriptLevel; // [inherited] + // The value mSize would have had if scriptminsize had never been applied + nscoord mScriptUnconstrainedSize; + nscoord mScriptMinSize; // [inherited] length + float mScriptSizeMultiplier; // [inherited] +#endif }; struct nsStyleColor : public nsStyleStruct { diff --git a/mozilla/layout/style/test/ListCSSProperties.cpp b/mozilla/layout/style/test/ListCSSProperties.cpp index 7bd44f9f44b..c2e40bf10bb 100644 --- a/mozilla/layout/style/test/ListCSSProperties.cpp +++ b/mozilla/layout/style/test/ListCSSProperties.cpp @@ -152,7 +152,10 @@ const char *gInaccessibleProperties[] = { "padding-left-ltr-source", "padding-left-rtl-source", "padding-right-ltr-source", - "padding-right-rtl-source" + "padding-right-rtl-source", + "-moz-script-level", // parsed by UA sheets only + "-moz-script-size-multiplier", + "-moz-script-min-size" }; inline int