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

This commit is contained in:
roc+@cs.cmu.edu 2008-01-08 14:36:46 -08:00
parent e6ce27c055
commit 459c356854
77 changed files with 2074 additions and 1294 deletions

View File

@ -53,6 +53,10 @@ ifdef MOZ_XTF
DIRS += xtf
endif
ifdef MOZ_MATHML
DIRS += mathml
endif
DIRS += events
ifdef ENABLE_TESTS

View File

@ -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

View File

@ -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,
};
/**

View File

@ -136,6 +136,7 @@ CPPSRCS = \
nsImageLoadingContent.cpp \
nsLineBreaker.cpp \
nsLoadListenerProxy.cpp \
nsMappedAttributeElement.cpp \
nsMappedAttributes.cpp \
nsNameSpaceManager.cpp \
nsNoDataProtocolContentPolicy.cpp \

View File

@ -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<nsMappedAttributes> mapped;
@ -651,7 +651,7 @@ nsAttrAndChildArray::MappedAttrCount() const
}
nsresult
nsAttrAndChildArray::GetModifiableMapped(nsGenericHTMLElement* aContent,
nsAttrAndChildArray::GetModifiableMapped(nsMappedAttributeElement* aContent,
nsHTMLStyleSheet* aSheet,
PRBool aWillAddAttr,
nsMappedAttributes** aModifiable)

View File

@ -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);

View File

@ -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 <mats.palmgren@bredband.net>
* Daniel Kraft <d@domob.eu>
*
* 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)
{
}

View File

@ -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 <d@domob.eu>
*
* 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_

View File

@ -45,7 +45,7 @@
#define nsMappedAttributes_h___
#include "nsAttrAndChildArray.h"
#include "nsGenericHTMLElement.h"
#include "nsMappedAttributeElement.h"
#include "nsIStyleRule.h"
class nsIAtom;

View File

@ -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__

View File

@ -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<nsIURI>
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
{

View File

@ -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<nsIURI> 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

View File

@ -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.
*/
{

View File

@ -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

View File

@ -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

View File

@ -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 <vladimir.sukhoy@gmail.com> (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

View File

@ -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 <vladimir.sukhoy@gmail.com> (original developer)
* Daniel Kraft <d@domob.eu> (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<nsIDOMNode *>(this);
} else if (aIID.Equals(NS_GET_IID(nsIDOMElement))) {
inst = static_cast<nsIDOMElement *>(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<nsIPresShell> 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);
}

View File

@ -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 <vladimir.sukhoy@gmail.com> (original developer)
* Daniel Kraft <d@domob.eu> (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

View File

@ -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 <vladimir.sukhoy@gmail.com> (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;
}

View File

@ -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

View File

@ -295,7 +295,7 @@ nsHistory::Go()
nsPresContext *pcx;
if (doc && (shell = doc->GetPrimaryShell()) &&
(pcx = shell->GetPresContext())) {
pcx->ClearStyleDataAndReflow();
pcx->RebuildAllStyleData();
}
return NS_OK;

View File

@ -892,7 +892,7 @@ nsLocation::Reload()
nsPresContext *pcx;
if (doc && (shell = doc->GetPrimaryShell()) &&
(pcx = shell->GetPresContext())) {
pcx->ClearStyleDataAndReflow();
pcx->RebuildAllStyleData();
}
return NS_OK;

View File

@ -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)

View File

@ -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<RestyleEvent> mRestyleEvent;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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 <mstyle> is the only tag which allows to set
* <mstyle displaystyle="true|false" scriptlevel="[+|-]number">
* to reset or increment the scriptlevel in a manual way.
* <mstyle displaystyle="true|false">
* Therefore <mstyle> 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 <mstyle> is the only tag which allows
* <mstyle displaystyle="true|false" scriptlevel="[+|-]number">
* to reset or increment the scriptlevel in a manual way.
* <mstyle displaystyle="true|false">
* Therefore <mstyle> 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 <mtag>base arguments</mtag>,
* 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 <mstyle> because that's
// the only tag where the attribute is allowed by the spec.
// Note: the flag is not set if the <mstyle> 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 <mstyle> and <mtable>
// 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))

View File

@ -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 <mstyle> 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 <math>...</math>
// 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 <math>
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 <math> 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<nsMathMLElement*>(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 <math> is the only parent
// e.g., it fixes <math> <mi>f</mi> <mo>q</mo> <mi>f</mi> <mo>I</mo> </math>
@ -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);

View File

@ -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___ */

View File

@ -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;
}

View File

@ -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<nsICSSStyleSheet> 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<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), "about:internal-mathml-attribute-stylesheet");
if (!uri)
return;
nsCOMPtr<nsICSSStyleSheet> 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<nsIDOMCSSStyleSheet> 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<nsIDocument> doc;
nsCOMPtr<nsIStyleSheet> sheet;
nsCOMPtr<nsICSSStyleSheet> cssSheet;
nsCOMPtr<nsIDOMCSSStyleSheet> 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<nsICSSRule> tmpRule;
cssSheet->GetStyleRuleAt(k, *getter_AddRefs(tmpRule));
nsCOMPtr<nsICSSStyleRule> 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:

View File

@ -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,

View File

@ -267,7 +267,8 @@ nsMathMLmfencedFrame::doReflow(nsPresContext* aPresContext,
PRInt32 i;
nsCOMPtr<nsIFontMetrics> 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);
//////////////////

View File

@ -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 <mfrac> element sets displaystyle to "false", or if it was already
// false increments scriptlevel by 1, within numerator and denominator.
// @see similar peculiarities for <mover>, <munder>, <munderover>
// 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);
}
// ----------------------

View File

@ -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;
};

View File

@ -73,7 +73,7 @@ nsMathMLmmultiscriptsFrame::TransmitAutomaticData()
// The REC says:
// The <mmultiscripts> 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<nsIFontMetrics> 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

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -111,10 +111,10 @@ nsMathMLmrootFrame::TransmitAutomaticData()
// The <mroot> 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;

View File

@ -124,7 +124,7 @@ nsMathMLmsqrtFrame::TransmitAutomaticData()
// The <msqrt> 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);

View File

@ -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 <mstyle> 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

View File

@ -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);

View File

@ -74,7 +74,7 @@ nsMathMLmsubFrame::TransmitAutomaticData()
// The <msub> 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);

View File

@ -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

View File

@ -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

View File

@ -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 <mtable>
// 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 <mtable>:
// 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 <mtr>:
// 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 <mtd>:
// groupalign : Not yet supported
// rowalign : in mathml.css

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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; }

View File

@ -0,0 +1,36 @@
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:m="http://www.w3.org/1998/Math/MathML">
<body>
<p><m:math>
<m:mstyle><m:mi style="font-size:48px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:24px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:18px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:18px;">Id</m:mi></m:mstyle>
</m:math></p>
<p><m:math>
<m:mstyle><m:mi style="font-size:96px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:192px;">Id</m:mi></m:mstyle>
</m:math></p>
<p><m:math>
<m:mstyle><m:mi style="font-size:48px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:96px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:192px;">Id</m:mi></m:mstyle>
</m:math></p>
<p><m:math>
<m:mstyle><m:mi style="font-size:24px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:48px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:96px;">Id</m:mi></m:mstyle>
</m:math></p>
<p><m:math>
<m:mstyle><m:mi style="font-size:18px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:24px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:48px;">Id</m:mi></m:mstyle>
</m:math></p>
<p><m:math>
<m:mstyle><m:mi style="font-size:18px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:18px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:24px;">Id</m:mi></m:mstyle>
</m:math></p>
</body>
</html>

View File

@ -0,0 +1,36 @@
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:m="http://www.w3.org/1998/Math/MathML">
<body>
<p><m:math><m:mstyle scriptlevel="0" scriptsizemultiplier="0.5" scriptminsize="18px" style="font-size:48px;">
<m:mi>Id</m:mi>
<m:mstyle scriptlevel="+1"><m:mi>Id</m:mi></m:mstyle>
<m:mstyle scriptlevel="+2"><m:mi>Id</m:mi></m:mstyle>
<m:mstyle scriptlevel="+3"><m:mi>Id</m:mi></m:mstyle>
</m:mstyle></m:math></p>
<p><m:math><m:mstyle scriptlevel="0" scriptsizemultiplier="0.5" scriptminsize="18px" style="font-size:48px;">
<m:mstyle scriptlevel="-1"><m:mi>Id</m:mi></m:mstyle>
<m:mstyle scriptlevel="-2"><m:mi>Id</m:mi></m:mstyle>
</m:mstyle></m:math></p>
<p><m:math><m:mstyle scriptlevel="0" scriptsizemultiplier="0.5" scriptminsize="18px" style="font-size:48px;">
<m:mstyle scriptlevel="+1"><m:mstyle scriptlevel="-1"><m:mi>Id</m:mi></m:mstyle></m:mstyle>
<m:mstyle scriptlevel="+1"><m:mstyle scriptlevel="-2"><m:mi>Id</m:mi></m:mstyle></m:mstyle>
<m:mstyle scriptlevel="+1"><m:mstyle scriptlevel="-3"><m:mi>Id</m:mi></m:mstyle></m:mstyle>
</m:mstyle></m:math></p>
<p><m:math><m:mstyle scriptlevel="0" scriptsizemultiplier="0.5" scriptminsize="18px" style="font-size:48px;">
<m:mstyle scriptlevel="+2"><m:mstyle scriptlevel="-1"><m:mi>Id</m:mi></m:mstyle></m:mstyle>
<m:mstyle scriptlevel="+2"><m:mstyle scriptlevel="-2"><m:mi>Id</m:mi></m:mstyle></m:mstyle>
<m:mstyle scriptlevel="+2"><m:mstyle scriptlevel="-3"><m:mi>Id</m:mi></m:mstyle></m:mstyle>
</m:mstyle></m:math></p>
<p><m:math><m:mstyle scriptlevel="0" scriptsizemultiplier="0.5" scriptminsize="18px" style="font-size:48px;">
<m:mstyle scriptlevel="+3"><m:mstyle scriptlevel="-1"><m:mi>Id</m:mi></m:mstyle></m:mstyle>
<m:mstyle scriptlevel="+3"><m:mstyle scriptlevel="-2"><m:mi>Id</m:mi></m:mstyle></m:mstyle>
<m:mstyle scriptlevel="+3"><m:mstyle scriptlevel="-3"><m:mi>Id</m:mi></m:mstyle></m:mstyle>
</m:mstyle></m:math></p>
<p><m:math><m:mstyle scriptlevel="0" scriptsizemultiplier="0.5" scriptminsize="18px" style="font-size:48px;">
<m:mstyle scriptlevel="+4"><m:mstyle scriptlevel="-1"><m:mi>Id</m:mi></m:mstyle></m:mstyle>
<m:mstyle scriptlevel="+4"><m:mstyle scriptlevel="-2"><m:mi>Id</m:mi></m:mstyle></m:mstyle>
<m:mstyle scriptlevel="+4"><m:mstyle scriptlevel="-3"><m:mi>Id</m:mi></m:mstyle></m:mstyle>
</m:mstyle></m:math></p>
</body>
</html>

View File

@ -0,0 +1,25 @@
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:m="http://www.w3.org/1998/Math/MathML">
<body>
<p><m:math>
<m:mstyle><m:mi style="font-size:18px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:10px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:48px;">Id</m:mi></m:mstyle>
</m:math></p>
<p><m:math>
<m:mstyle><m:mi style="font-size:24px;">Id</m:mi></m:mstyle>
</m:math></p>
<p><m:math>
<m:mstyle><m:mi style="font-size:10px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:20px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:40px;">Id</m:mi></m:mstyle>
</m:math></p>
<p><m:math>
<m:mstyle><m:mi style="font-size:48px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:48px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:18px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:12px;">Id</m:mi></m:mstyle>
</m:math></p>
</body>
</html>

View File

@ -0,0 +1,38 @@
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:m="http://www.w3.org/1998/Math/MathML">
<body>
<!-- Test interactions between CSS font-size and scriptlevel changes -->
<p><m:math><m:mstyle scriptlevel="0" scriptsizemultiplier="0.5" scriptminsize="18px" style="font-size:48px;">
<m:mstyle scriptlevel="+5"><m:mi>Id</m:mi></m:mstyle>
<!-- Test that we can explicitly go below scriptminsize -->
<m:mi style="font-size:10px;">Id</m:mi>
<!-- Test that a relative font-size ignores the scriptlevel change in the same element -->
<m:mstyle scriptlevel="+5" style="font-size:100%;"><m:mi>Id</m:mi></m:mstyle>
</m:mstyle></m:math></p>
<p><m:math><m:mstyle scriptlevel="0" scriptsizemultiplier="0.5" scriptminsize="18px" style="font-size:48px;">
<!-- Test that scriptlevel changes are incremental (this should be 24px) -->
<m:mstyle scriptlevel="+1" style="font-size:48px;"><m:mstyle scriptlevel="+1"><m:mi>Id</m:mi></m:mstyle></m:mstyle>
</m:mstyle></m:math></p>
<p><m:math><m:mstyle scriptlevel="0" scriptsizemultiplier="0.5" scriptminsize="18px" style="font-size:48px;">
<!-- Decreasing the font size due to a scriptlevel change should do nothing when we're below minscriptsize -->
<m:mstyle style="font-size:10px;"><m:mstyle scriptlevel="+1"><m:mi>Id</m:mi></m:mstyle></m:mstyle>
<!-- but we can increase -->
<m:mstyle style="font-size:10px;"><m:mstyle scriptlevel="-1"><m:mi>Id</m:mi></m:mstyle></m:mstyle>
<m:mstyle style="font-size:10px;"><m:mstyle scriptlevel="-2"><m:mi>Id</m:mi></m:mstyle></m:mstyle>
</m:mstyle></m:math></p>
<p><m:math><m:mstyle scriptlevel="0" scriptsizemultiplier="0.5" scriptminsize="18px" style="font-size:48px;">
<!-- An absolute font-size value resets the unconstrained size to that value, so we
can increase above that value with a negative scriptlevel change -->
<m:mstyle scriptlevel="+5"><m:mstyle style="font-size:24px;"><m:mstyle scriptlevel="-1"><m:mi>Id</m:mi></m:mstyle></m:mstyle></m:mstyle>
<!-- An relative font-size value is applied to the unconstrained size -->
<m:mstyle scriptlevel="+2"><m:mstyle style="font-size:200%;"><m:mstyle scriptlevel="-1"><m:mi>Id</m:mi></m:mstyle></m:mstyle></m:mstyle>
<!-- The unconstrained size does not cap the font size to below scriptminsize (so this is 18px) -->
<m:mstyle scriptlevel="+2"><m:mstyle style="font-size:50%;"><m:mstyle scriptlevel="-1"><m:mi>Id</m:mi></m:mstyle></m:mstyle></m:mstyle>
<!-- The unconstrained size cap the font size otherwise (so this is 12px) -->
<m:mstyle scriptlevel="+2"><m:mstyle style="font-size:50%;" scriptminsize="0"><m:mstyle scriptlevel="-1"><m:mi>Id</m:mi></m:mstyle></m:mstyle></m:mstyle>
</m:mstyle></m:math></p>
</body>
</html>

View File

@ -0,0 +1,67 @@
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:m="http://www.w3.org/1998/Math/MathML">
<body>
<p><m:math>
<m:mstyle><m:mi style="font-size:24px;">Id</m:mi></m:mstyle>
</m:math></p>
<p><m:math>
<m:mstyle><m:mi style="font-size:30px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:30px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:30px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:30px;">Id</m:mi></m:mstyle>
</m:math></p>
<p><m:math>
<m:mstyle><m:mi style="font-size:small;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:medium;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:large;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:48px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:48px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:48px;">Id</m:mi></m:mstyle>
</m:math></p>
<p><m:math>
<m:mstyle><m:mi style="font-family:Verdana; font-size:48px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-family:monospace; font-size:48px;">Id</m:mi></m:mstyle>
</m:math></p>
<p><m:math>
<m:mstyle><m:mi style="font-size:48px; background:green;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:48px; background:green;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:48px; background:green;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:48px; background:green;">Id</m:mi></m:mstyle>
</m:math></p>
<p><m:math>
<m:mstyle><m:mi style="font-size:48px; background:rgb(0,255,0);">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:48px; background:rgb(0,255,0);">Id</m:mi></m:mstyle>
</m:math></p>
<p><m:math>
<m:mstyle><m:mi style="font-size:48px; color:green;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:48px; color:green;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:48px; color:green;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:48px; color:green;">Id</m:mi></m:mstyle>
</m:math></p>
<p><m:math>
<m:mstyle><m:mi style="font-size:48px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:48px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:48px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:48px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:48px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:48px;">Id</m:mi></m:mstyle>
</m:math></p>
<p><m:math>
<m:mstyle><m:mi style="font-size:24px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:24px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:24px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:24px;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:0;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:0;">Id</m:mi></m:mstyle>
<m:mstyle><m:mi style="font-size:0;">Id</m:mi></m:mstyle>
</m:math></p>
</body>
</html>

View File

@ -0,0 +1,78 @@
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:m="http://www.w3.org/1998/Math/MathML">
<body>
<!-- Test attribute parsing -->
<p><m:math><m:mstyle scriptlevel="0" scriptsizemultiplier="0.5" scriptminsize="18px" style="font-size:48px;">
<!-- MathML number attributes cannot start with '+' -->
<m:mstyle scriptsizemultiplier="+1"><m:mstyle scriptlevel="+1"><m:mi>Id</m:mi></m:mstyle></m:mstyle>
</m:mstyle></m:math></p>
<p><m:math><m:mstyle scriptlevel="0" scriptsizemultiplier="0.5" scriptminsize="18px" style="font-size:48px;">
<m:mstyle mathsize="30px"><m:mi>Id</m:mi></m:mstyle>
<m:mstyle fontsize="30px"><m:mi>Id</m:mi></m:mstyle>
<!-- mathsize takes priority over fontsize -->
<m:mstyle mathsize="30px" fontsize="20px"><m:mi>Id</m:mi></m:mstyle>
<!-- CSS takes priority over mathsize and fontsize -->
<m:mstyle mathsize="24px" fontsize="20px" style="font-size:30px;"><m:mi>Id</m:mi></m:mstyle>
</m:mstyle></m:math></p>
<p><m:math><m:mstyle scriptlevel="0" scriptsizemultiplier="0.5" scriptminsize="18px" style="font-size:48px;">
<m:mstyle mathsize="small"><m:mi>Id</m:mi></m:mstyle>
<m:mstyle mathsize="normal"><m:mi>Id</m:mi></m:mstyle>
<m:mstyle mathsize="big"><m:mi>Id</m:mi></m:mstyle>
<!-- check that fontsize doesn't accept those values -->
<m:mstyle fontsize="small"><m:mi>Id</m:mi></m:mstyle>
<m:mstyle fontsize="normal"><m:mi>Id</m:mi></m:mstyle>
<m:mstyle fontsize="big"><m:mi>Id</m:mi></m:mstyle>
</m:mstyle></m:math></p>
<p><m:math><m:mstyle scriptlevel="0" scriptsizemultiplier="0.5" scriptminsize="18px" style="font-size:48px;">
<m:mstyle fontfamily="Verdana"><m:mi>Id</m:mi></m:mstyle>
<m:mstyle fontfamily="Verdana" style="font-family:monospace;"><m:mi>Id</m:mi></m:mstyle>
</m:mstyle></m:math></p>
<p><m:math><m:mstyle scriptlevel="0" scriptsizemultiplier="0.5" scriptminsize="18px" style="font-size:48px;">
<m:mstyle mathbackground="green"><m:mi>Id</m:mi></m:mstyle>
<m:mstyle background="green"><m:mi>Id</m:mi></m:mstyle>
<!-- mathsize takes priority over fontsize -->
<m:mstyle mathbackground="green" background="red"><m:mi>Id</m:mi></m:mstyle>
<!-- CSS takes priority over mathsize and fontsize -->
<m:mstyle mathbackground="red" background="yellow" style="background:green;"><m:mi>Id</m:mi></m:mstyle>
</m:mstyle></m:math></p>
<p><m:math><m:mstyle scriptlevel="0" scriptsizemultiplier="0.5" scriptminsize="18px" style="font-size:48px;">
<m:mstyle mathbackground="#0F0"><m:mi>Id</m:mi></m:mstyle>
<m:mstyle mathbackground="#00FF00"><m:mi>Id</m:mi></m:mstyle>
</m:mstyle></m:math></p>
<p><m:math><m:mstyle scriptlevel="0" scriptsizemultiplier="0.5" scriptminsize="18px" style="font-size:48px;">
<m:mstyle mathcolor="green"><m:mi>Id</m:mi></m:mstyle>
<m:mstyle color="green"><m:mi>Id</m:mi></m:mstyle>
<!-- mathsize takes priority over fontsize -->
<m:mstyle mathcolor="green" color="red"><m:mi>Id</m:mi></m:mstyle>
<!-- CSS takes priority over mathsize and fontsize -->
<m:mstyle mathcolor="red" color="yellow" style="color:green;"><m:mi>Id</m:mi></m:mstyle>
</m:mstyle></m:math></p>
<p><m:math><m:mstyle scriptlevel="0" scriptsizemultiplier="0.5" scriptminsize="18px" style="font-size:48px;">
<!-- test invalid values for MathML length attributes -->
<m:mstyle mathsize="20 px"><m:mi>Id</m:mi></m:mstyle>
<m:mstyle mathsize="20PX"><m:mi>Id</m:mi></m:mstyle>
<m:mstyle mathsize="20"><m:mi>Id</m:mi></m:mstyle>
<m:mstyle mathsize=".px"><m:mi>Id</m:mi></m:mstyle>
<m:mstyle mathsize="..px"><m:mi>Id</m:mi></m:mstyle>
<m:mstyle mathsize="+20px"><m:mi>Id</m:mi></m:mstyle>
</m:mstyle></m:math></p>
<p><m:math><m:mstyle scriptlevel="0" scriptsizemultiplier="0.5" scriptminsize="18px" style="font-size:48px;">
<!-- test valid values for MathML length attributes -->
<m:mstyle mathsize=" 24px "><m:mi>Id</m:mi></m:mstyle>
<m:mstyle mathsize="24.0px"><m:mi>Id</m:mi></m:mstyle>
<m:mstyle mathsize="24.px"><m:mi>Id</m:mi></m:mstyle>
<m:mstyle mathsize="50%"><m:mi>Id</m:mi></m:mstyle>
<m:mstyle mathsize=".0px"><m:mi>Id</m:mi></m:mstyle>
<m:mstyle mathsize="-0px"><m:mi>Id</m:mi></m:mstyle>
<m:mstyle mathsize="0"><m:mi>Id</m:mi></m:mstyle>
</m:mstyle></m:math></p>
</body>
</html>

View File

@ -0,0 +1,11 @@
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:m="http://www.w3.org/1998/Math/MathML">
<head>
<style>
.v { font: 48px "Verdana"; }
</style>
</head>
<body>
<p><span class="v">Hello</span></p>
<m:math><m:mstyle><m:mi style="font-size:24px; font-family:Verdana">Id</m:mi></m:mstyle></m:math>
</body>
</html>

View File

@ -0,0 +1,41 @@
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
<head>
<style>
/* test the situation where an nsStyleFont is cached in the rule tree but we have to blow it
away because MathML is suddenly introduced */
.v { font: 48px "Verdana"; }
</style>
<script>
function addMathML() {
function createMathMLElement(tag) {
return document.createElementNS("http://www.w3.org/1998/Math/MathML", tag);
}
var body = document.getElementById("body");
body.offsetTop;
// if we don't blow away the rule tree correctly, then we will cache an nsStyleFont with
// a scriptsizemultiplier of 0.71 (the default) and use it to style mstyle2, so the
// scriptlevel change will not scale the text by 0.5
var math = createMathMLElement("math");
var mstyle = createMathMLElement("mstyle");
mstyle.setAttribute("scriptsizemultiplier", "0.5");
var mstyle2 = createMathMLElement("mstyle");
mstyle2.setAttribute("class", "v");
var mstyle3 = createMathMLElement("mstyle");
mstyle3.setAttribute("scriptlevel", "+1");
var mi = createMathMLElement("mi");
mi.textContent = "Id";
mstyle3.appendChild(mi);
mstyle2.appendChild(mstyle3);
mstyle.appendChild(mstyle2);
math.appendChild(mstyle);
body.appendChild(math);
document.documentElement.className = '';
}
</script>
</head>
<body id="body" onload="addMathML()">
<p><span class="v">Hello</span></p>
</body>
</html>

View File

@ -0,0 +1,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:m="http://www.w3.org/1998/Math/MathML">
<body>
<p><m:math><m:mstyle scriptlevel="0" scriptsizemultiplier="0.5" scriptminsize="18px" style="font-size:48px;">
<m:mstyle scriptlevel="+1"><m:mstyle style="font-family:serif;"><m:mi>Id</m:mi></m:mstyle></m:mstyle>
</m:mstyle></m:math></p>
</body>
</html>

View File

@ -0,0 +1,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:m="http://www.w3.org/1998/Math/MathML">
<body>
<p><m:math><m:mstyle scriptlevel="0" scriptsizemultiplier="0.5" scriptminsize="18px" style="font-size:48px;">
<m:mstyle style="font-family:sans-serif;"><m:mstyle scriptlevel="+1"><m:mstyle style="font-family:serif;"><m:mi>Id</m:mi></m:mstyle></m:mstyle></m:mstyle>
</m:mstyle></m:math></p>
</body>
</html>

View File

@ -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

View File

@ -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);

View File

@ -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?

View File

@ -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")

View File

@ -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;
}

View File

@ -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
};

View File

@ -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<nsIFontMetrics> fm = aPresContext->GetMetricsFor(*font);
nsFont font = aStyleFont->mFont;
font.size = aFontSize;
nsCOMPtr<nsIFontMetrics> 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<const char*>(&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<const nsCSSFont&>(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) {
// <font size="7"> 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) {
// <font size="7"> 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;
}

View File

@ -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,

View File

@ -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*

View File

@ -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 {

View File

@ -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