Bug 677036 - Unify parsing of length and mpadded attributes. r=karlt

This commit is contained in:
Frédéric Wang 2012-05-15 18:30:14 -04:00
parent 5748bfbc37
commit b55dc91e7f
12 changed files with 428 additions and 262 deletions

View File

@ -243,32 +243,88 @@ nsMathMLElement::GetAttributeMappingFunction() const
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 */ bool
nsMathMLElement::ParseNamedSpaceValue(const nsString& aString,
nsCSSValue& aCSSValue,
PRUint32 aFlags)
{
PRInt32 i = 0;
// See if it is one of the 'namedspace' (ranging -7/18em, -6/18, ... 7/18em)
if (aString.EqualsLiteral("veryverythinmathspace")) {
i = 1;
} else if (aString.EqualsLiteral("verythinmathspace")) {
i = 2;
} else if (aString.EqualsLiteral("thinmathspace")) {
i = 3;
} else if (aString.EqualsLiteral("mediummathspace")) {
i = 4;
} else if (aString.EqualsLiteral("thickmathspace")) {
i = 5;
} else if (aString.EqualsLiteral("verythickmathspace")) {
i = 6;
} else if (aString.EqualsLiteral("veryverythickmathspace")) {
i = 7;
} else if (aFlags & PARSE_ALLOW_NEGATIVE) {
if (aString.EqualsLiteral("negativeveryverythinmathspace")) {
i = -1;
} else if (aString.EqualsLiteral("negativeverythinmathspace")) {
i = -2;
} else if (aString.EqualsLiteral("negativethinmathspace")) {
i = -3;
} else if (aString.EqualsLiteral("negativemediummathspace")) {
i = -4;
} else if (aString.EqualsLiteral("negativethickmathspace")) {
i = -5;
} else if (aString.EqualsLiteral("negativeverythickmathspace")) {
i = -6;
} else if (aString.EqualsLiteral("negativeveryverythickmathspace")) {
i = -7;
}
}
if (0 != i) {
aCSSValue.SetFloatValue(float(i)/float(18), eCSSUnit_EM);
return true;
}
return false;
}
// The REC says:
//
// "Most presentation elements have attributes that accept values representing
// lengths to be used for size, spacing or similar properties. The syntax of a
// length is specified as
//
// number | number unit | namedspace
//
// There should be no space between the number and the unit of a length."
//
// "A trailing '%' represents a percent of the default value. The default
// value, or how it is obtained, is listed in the table of attributes for each
// element. [...] A number without a unit is intepreted as a multiple of the
// default value."
//
// "The possible units in MathML are:
//
// Unit Description
// em an em (font-relative unit traditionally used for horizontal lengths)
// ex an ex (font-relative unit traditionally used for vertical lengths)
// px pixels, or size of a pixel in the current 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"
//
// The numbers are defined that way:
// - unsigned-number: "a string of decimal digits with up to one decimal point
// (U+002E), representing a non-negative terminating decimal number (a type of
// rational number)"
// - number: "an optional prefix of '-' (U+002D), followed by an unsigned
// number, representing a terminating decimal number (a type of rational
// number)"
//
/* static */ bool
nsMathMLElement::ParseNumericValue(const nsString& aString,
nsCSSValue& aCSSValue,
@ -281,6 +337,10 @@ nsMathMLElement::ParseNumericValue(const nsString& aString,
if (!stringLength)
return false;
if (ParseNamedSpaceValue(aString, aCSSValue, aFlags)) {
return true;
}
nsAutoString number, unit;
// see if the negative sign is there
@ -289,10 +349,6 @@ nsMathMLElement::ParseNumericValue(const nsString& aString,
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
@ -358,6 +414,14 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
nsRuleData* aData)
{
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Font)) {
// scriptsizemultiplier
//
// "Specifies the multiplier to be used to adjust font size due to changes
// in scriptlevel.
//
// values: number
// default: 0.71
//
const nsAttrValue* value =
aAttributes->GetAttr(nsGkAtoms::scriptsizemultiplier_);
nsCSSValue* scriptSizeMultiplier =
@ -377,6 +441,18 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
}
}
// scriptminsize
//
// "Specifies the minimum font size allowed due to changes in scriptlevel.
// Note that this does not limit the font size due to changes to mathsize."
//
// values: length
// default: 8pt
//
// We don't allow negative values.
// XXXfredw Should we allow unitless values? (bug 411227)
// XXXfredw Does a relative unit give a multiple of the default value?
//
value = aAttributes->GetAttr(nsGkAtoms::scriptminsize_);
nsCSSValue* scriptMinSize = aData->ValueForScriptMinSize();
if (value && value->Type() == nsAttrValue::eString &&
@ -384,6 +460,17 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
ParseNumericValue(value->GetStringValue(), *scriptMinSize, 0);
}
// scriptlevel
//
// "Changes the scriptlevel in effect for the children. When the value is
// given without a sign, it sets scriptlevel to the specified value; when a
// sign is given, it increments ("+") or decrements ("-") the current
// value. (Note that large decrements can result in negative values of
// scriptlevel, but these values are considered legal.)"
//
// values: ( "+" | "-" )? unsigned-integer
// default: inherited
//
value = aAttributes->GetAttr(nsGkAtoms::scriptlevel_);
nsCSSValue* scriptLevel = aData->ValueForScriptLevel();
if (value && value->Type() == nsAttrValue::eString &&
@ -408,6 +495,28 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
}
}
// mathsize
//
// "Specifies the size to display the token content. The values 'small' and
// 'big' choose a size smaller or larger than the current font size, but
// leave the exact proportions unspecified; 'normal' is allowed for
// completeness, but since it is equivalent to '100%' or '1em', it has no
// effect."
//
// values: "small" | "normal" | "big" | length
// default: inherited
//
// fontsize
//
// "Specified the size for the token. Deprecated in favor of mathsize."
//
// values: length
// default: inherited
//
// In both cases, we don't allow negative values.
// XXXfredw Should we allow unitless values? (bug 411227)
// XXXfredw Does a relative unit give a multiple of the default value?
//
bool parseSizeKeywords = true;
value = aAttributes->GetAttr(nsGkAtoms::mathsize_);
if (!value) {
@ -435,6 +544,14 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
}
}
// fontfamily
//
// "Should be the name of a font that may be available to a MathML renderer,
// or a CSS font specification; See Section 6.5 Using CSS with MathML and
// CSS for more information. Deprecated in favor of mathvariant."
//
// values: string
//
value = aAttributes->GetAttr(nsGkAtoms::fontfamily_);
nsCSSValue* fontFamily = aData->ValueForFontFamily();
if (value && value->Type() == nsAttrValue::eString &&
@ -443,6 +560,24 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
}
}
// mathbackground
//
// "Specifies the background color to be used to fill in the bounding box of
// the element and its children. The default, 'transparent', lets the
// background color, if any, used in the current rendering context to show
// through."
//
// values: color | "transparent"
// default: "transparent"
//
// background
//
// "Specified the background color to be used to fill in the bounding box of
// the element and its children. Deprecated in favor of mathbackground."
//
// values: color | "transparent"
// default: "transparent"
//
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Background)) {
const nsAttrValue* value =
aAttributes->GetAttr(nsGkAtoms::mathbackground_);
@ -458,6 +593,23 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
}
}
// mathcolor
//
// "Specifies the foreground color to use when drawing the components of this
// element, such as the content for token elements or any lines, surds, or
// other decorations. It also establishes the default mathcolor used for
// child elements when used on a layout element."
//
// values: color
// default: inherited
//
// color
//
// "Specified the color for the token. Deprecated in favor of mathcolor."
//
// values: color
// default: inherited
//
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Color)) {
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::mathcolor_);
if (!value) {

View File

@ -89,6 +89,10 @@ public:
PARSE_ALLOW_UNITLESS = 0x01, // unitless 0 will be turned into 0px
PARSE_ALLOW_NEGATIVE = 0x02
};
static bool ParseNamedSpaceValue(const nsString& aString,
nsCSSValue& aCSSValue,
PRUint32 aFlags);
static bool ParseNumericValue(const nsString& aString,
nsCSSValue& aCSSValue,
PRUint32 aFlags);

View File

@ -380,95 +380,33 @@ nsMathMLFrame::CalcLength(nsPresContext* aPresContext,
return 0;
}
/* static */ bool
nsMathMLFrame::ParseNamedSpaceValue(nsIFrame* aMathMLmstyleFrame,
nsString& aString,
nsCSSValue& aCSSValue)
/* static */ void
nsMathMLFrame::ParseNumericValue(const nsString& aString,
nscoord* aLengthValue,
PRUint32 aFlags,
nsPresContext* aPresContext,
nsStyleContext* aStyleContext)
{
aCSSValue.Reset();
aString.CompressWhitespace(); // aString is not a const in this code...
if (!aString.Length()) return false;
nsCSSValue cssValue;
// See if it is one of the 'namedspace' (ranging 1/18em...7/18em)
PRInt32 i = 0;
nsIAtom* namedspaceAtom = nsnull;
if (aString.EqualsLiteral("veryverythinmathspace")) {
i = 1;
namedspaceAtom = nsGkAtoms::veryverythinmathspace_;
}
else if (aString.EqualsLiteral("verythinmathspace")) {
i = 2;
namedspaceAtom = nsGkAtoms::verythinmathspace_;
}
else if (aString.EqualsLiteral("thinmathspace")) {
i = 3;
namedspaceAtom = nsGkAtoms::thinmathspace_;
}
else if (aString.EqualsLiteral("mediummathspace")) {
i = 4;
namedspaceAtom = nsGkAtoms::mediummathspace_;
}
else if (aString.EqualsLiteral("thickmathspace")) {
i = 5;
namedspaceAtom = nsGkAtoms::thickmathspace_;
}
else if (aString.EqualsLiteral("verythickmathspace")) {
i = 6;
namedspaceAtom = nsGkAtoms::verythickmathspace_;
}
else if (aString.EqualsLiteral("veryverythickmathspace")) {
i = 7;
namedspaceAtom = nsGkAtoms::veryverythickmathspace_;
}
else if (aString.EqualsLiteral("negativeveryverythinmathspace")) {
i = -1;
namedspaceAtom = nsGkAtoms::negativeveryverythinmathspace_;
}
else if (aString.EqualsLiteral("negativeverythinmathspace")) {
i = -2;
namedspaceAtom = nsGkAtoms::negativeverythinmathspace_;
}
else if (aString.EqualsLiteral("negativethinmathspace")) {
i = -3;
namedspaceAtom = nsGkAtoms::negativethinmathspace_;
}
else if (aString.EqualsLiteral("negativemediummathspace")) {
i = -4;
namedspaceAtom = nsGkAtoms::negativemediummathspace_;
}
else if (aString.EqualsLiteral("negativethickmathspace")) {
i = -5;
namedspaceAtom = nsGkAtoms::negativethickmathspace_;
}
else if (aString.EqualsLiteral("negativeverythickmathspace")) {
i = -6;
namedspaceAtom = nsGkAtoms::negativeverythickmathspace_;
}
else if (aString.EqualsLiteral("negativeveryverythickmathspace")) {
i = -7;
namedspaceAtom = nsGkAtoms::negativeveryverythickmathspace_;
if (!nsMathMLElement::ParseNumericValue(aString, cssValue, aFlags)) {
// Invalid attribute value. aLengthValue remains unchanged, so the default
// length value is used.
return;
}
if (0 != i) {
if (aMathMLmstyleFrame) {
// see if there is a <mstyle> that has overriden the default value
// GetAttribute() will recurse all the way up into the <mstyle> hierarchy
nsAutoString value;
GetAttribute(nsnull, aMathMLmstyleFrame, namedspaceAtom, value);
if (!value.IsEmpty()) {
if (ParseNumericValue(value, aCSSValue) &&
aCSSValue.IsLengthUnit()) {
return true;
}
}
}
nsCSSUnit unit = cssValue.GetUnit();
// fall back to the default value
aCSSValue.SetFloatValue(float(i)/float(18), eCSSUnit_EM);
return true;
if (unit == eCSSUnit_Percent || unit == eCSSUnit_Number) {
// Relative units. A multiple of the default length value is used.
*aLengthValue = NSToCoordRound(*aLengthValue * (unit == eCSSUnit_Percent ?
cssValue.GetPercentValue() :
cssValue.GetFloatValue()));
return;
}
return false;
// Absolute units.
*aLengthValue = CalcLength(aPresContext, aStyleContext, cssValue);
}
// ================

View File

@ -186,24 +186,19 @@ public:
// utilities to parse and retrieve numeric values in CSS units
// All values are stored in twips.
static bool
ParseNumericValue(const nsString& aString,
nsCSSValue& aCSSValue) {
return nsMathMLElement::ParseNumericValue(aString, aCSSValue,
nsMathMLElement::PARSE_ALLOW_NEGATIVE |
nsMathMLElement::PARSE_ALLOW_UNITLESS);
}
// @pre aLengthValue is the default length value of the attribute.
// @post aLengthValue is the length value computed from the attribute.
static void ParseNumericValue(const nsString& aString,
nscoord* aLengthValue,
PRUint32 aFlags,
nsPresContext* aPresContext,
nsStyleContext* aStyleContext);
static nscoord
CalcLength(nsPresContext* aPresContext,
nsStyleContext* aStyleContext,
const nsCSSValue& aCSSValue);
static bool
ParseNamedSpaceValue(nsIFrame* aMathMLmstyleFrame,
nsString& aString,
nsCSSValue& aCSSValue);
static eMathMLFrameType
GetMathMLFrameTypeFor(nsIFrame* aFrame)
{

View File

@ -124,6 +124,15 @@ nsMathMLmfracFrame::CalcLineThickness(nsPresContext* aPresContext,
nscoord lineThickness = aDefaultRuleThickness;
nscoord minimumThickness = onePixel;
// linethickness
//
// "Specifies the thickness of the horizontal 'fraction bar', or 'rule'. The
// default value is 'medium', 'thin' is thinner, but visible, 'thick' is
// thicker; the exact thickness of these is left up to the rendering agent."
//
// values: length | "thin" | "medium" | "thick"
// default: medium
//
if (!aThicknessAttribute.IsEmpty()) {
if (aThicknessAttribute.EqualsLiteral("thin")) {
lineThickness = NSToCoordFloor(defaultThickness * THIN_FRACTION_LINE);
@ -142,17 +151,12 @@ nsMathMLmfracFrame::CalcLineThickness(nsPresContext* aPresContext,
if (lineThickness < defaultThickness + onePixel)
lineThickness = defaultThickness + onePixel;
}
else { // see if it is a plain number, or a percentage, or a h/v-unit like 1ex, 2px, 1em
nsCSSValue cssValue;
if (ParseNumericValue(aThicknessAttribute, cssValue)) {
nsCSSUnit unit = cssValue.GetUnit();
if (eCSSUnit_Number == unit)
lineThickness = nscoord(float(defaultThickness) * cssValue.GetFloatValue());
else if (eCSSUnit_Percent == unit)
lineThickness = nscoord(float(defaultThickness) * cssValue.GetPercentValue());
else if (eCSSUnit_Null != unit)
lineThickness = CalcLength(aPresContext, aStyleContext, cssValue);
}
else {
// length value
lineThickness = defaultThickness;
ParseNumericValue(aThicknessAttribute, &lineThickness,
nsMathMLElement::PARSE_ALLOW_UNITLESS,
aPresContext, aStyleContext);
}
}

View File

@ -23,6 +23,7 @@
* Roger B. Sidje <rbs@maths.uq.edu.au>
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
* Shyjan Mahamud <mahamud@cs.cmu.edu> (added TeX rendering rules)
* Frederic Wang <fred.wang@free.fr>
*
* 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"),
@ -120,24 +121,42 @@ nsMathMLmmultiscriptsFrame::ProcessAttributes()
mSubScriptShift = 0;
mSupScriptShift = 0;
// check if the subscriptshift attribute is there
// subscriptshift
//
// "Specifies the minimum amount to shift the baseline of subscript down; the
// default is for the rendering agent to use its own positioning rules."
//
// values: length
// default: automatic
//
// We use 0 as the default value so unitless values can be ignored.
// XXXfredw Should we forbid negative values? (bug 411227)
//
nsAutoString value;
GetAttribute(mContent, mPresentationData.mstyle,
nsGkAtoms::subscriptshift_, value);
if (!value.IsEmpty()) {
nsCSSValue cssValue;
if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) {
mSubScriptShift = CalcLength(PresContext(), mStyleContext, cssValue);
}
ParseNumericValue(value, &mSubScriptShift,
nsMathMLElement::PARSE_ALLOW_NEGATIVE,
PresContext(), mStyleContext);
}
// check if the superscriptshift attribute is there
// superscriptshift
//
// "Specifies the minimum amount to shift the baseline of superscript up; the
// default is for the rendering agent to use its own positioning rules."
//
// values: length
// default: automatic
//
// We use 0 as the default value so unitless values can be ignored.
// XXXfredw Should we forbid negative values? (bug 411227)
//
GetAttribute(mContent, mPresentationData.mstyle,
nsGkAtoms::superscriptshift_, value);
if (!value.IsEmpty()) {
nsCSSValue cssValue;
if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) {
mSupScriptShift = CalcLength(PresContext(), mStyleContext, cssValue);
}
ParseNumericValue(value, &mSupScriptShift,
nsMathMLElement::PARSE_ALLOW_NEGATIVE,
PresContext(), mStyleContext);
}
}

View File

@ -413,15 +413,24 @@ nsMathMLmoFrame::ProcessOperatorData()
// If we are an accent without explicit lspace="." or rspace=".",
// we will ignore our default leading/trailing space
// lspace = number h-unit | namedspace
// lspace
//
// "Specifies the leading space appearing before the operator"
//
// values: length
// default: set by dictionary (thickmathspace)
//
// XXXfredw Should we allow negative values? (bug 411227) They will be made
// positive by the rounding below.
// XXXfredw Should we allow relative values? They will give a multiple of the
// current leading space, which is not necessarily the default one.
//
nscoord leadingSpace = mEmbellishData.leadingSpace;
GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::lspace_,
value);
if (!value.IsEmpty()) {
nsCSSValue cssValue;
if (ParseNumericValue(value, cssValue) ||
ParseNamedSpaceValue(mPresentationData.mstyle, value, cssValue))
{
if (nsMathMLElement::ParseNumericValue(value, cssValue, 0)) {
if ((eCSSUnit_Number == cssValue.GetUnit()) && !cssValue.GetFloatValue())
leadingSpace = 0;
else if (cssValue.IsLengthUnit())
@ -430,15 +439,24 @@ nsMathMLmoFrame::ProcessOperatorData()
}
}
// rspace = number h-unit | namedspace
// rspace
//
// "Specifies the trailing space appearing after the operator"
//
// values: length
// default: set by dictionary (thickmathspace)
//
// XXXfredw Should we allow negative values? (bug 411227) They will be made
// positive by the rounding below.
// XXXfredw Should we allow relative values? They will give a multiple of the
// current trailing space, which is not necessarily the default one.
//
nscoord trailingSpace = mEmbellishData.trailingSpace;
GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::rspace_,
value);
if (!value.IsEmpty()) {
nsCSSValue cssValue;
if (ParseNumericValue(value, cssValue) ||
ParseNamedSpaceValue(mPresentationData.mstyle, value, cssValue))
{
if (nsMathMLElement::ParseNumericValue(value, cssValue, 0)) {
if ((eCSSUnit_Number == cssValue.GetUnit()) && !cssValue.GetFloatValue())
trailingSpace = 0;
else if (cssValue.IsLengthUnit())
@ -503,15 +521,27 @@ nsMathMLmoFrame::ProcessOperatorData()
else if (value.EqualsLiteral("true"))
mFlags |= NS_MATHML_OPERATOR_SYMMETRIC;
// minsize = number [ v-unit | h-unit ] | namedspace
// minsize
//
// "Specifies the minimum size of the operator when stretchy"
//
// values: length
// default: set by dictionary (1em)
//
// We don't allow negative values.
// Note: Contrary to other "length" values, unitless and percentage do not
// give a multiple of the defaut value but a multiple of the operator at
// normal size.
//
mMinSize = 0.0;
GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::minsize_,
value);
if (!value.IsEmpty()) {
nsCSSValue cssValue;
if (ParseNumericValue(value, cssValue) ||
ParseNamedSpaceValue(mPresentationData.mstyle, value, cssValue))
{
if (nsMathMLElement::ParseNumericValue(value, cssValue,
nsMathMLElement::
PARSE_ALLOW_UNITLESS)) {
nsCSSUnit unit = cssValue.GetUnit();
if (eCSSUnit_Number == unit)
mMinSize = cssValue.GetFloatValue();
@ -521,32 +551,29 @@ nsMathMLmoFrame::ProcessOperatorData()
mMinSize = float(CalcLength(presContext, mStyleContext, cssValue));
mFlags |= NS_MATHML_OPERATOR_MINSIZE_ABSOLUTE;
}
if ((eCSSUnit_Number == unit) || (eCSSUnit_Percent == unit)) {
// see if the multiplicative inheritance should be from <mstyle>
GetAttribute(nsnull, mPresentationData.mstyle,
nsGkAtoms::minsize_, value);
if (!value.IsEmpty()) {
if (ParseNumericValue(value, cssValue)) {
if (cssValue.IsLengthUnit()) {
mMinSize *= float(CalcLength(presContext, mStyleContext, cssValue));
mFlags |= NS_MATHML_OPERATOR_MINSIZE_ABSOLUTE;
}
}
}
}
}
}
// maxsize = number [ v-unit | h-unit ] | namedspace | infinity
// maxsize
//
// "Specifies the maximum size of the operator when stretchy"
//
// values: length | "infinity"
// default: set by dictionary (infinity)
//
// We don't allow negative values.
// Note: Contrary to other "length" values, unitless and percentage do not
// give a multiple of the defaut value but a multiple of the operator at
// normal size.
//
mMaxSize = NS_MATHML_OPERATOR_SIZE_INFINITY;
GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::maxsize_,
value);
if (!value.IsEmpty()) {
nsCSSValue cssValue;
if (ParseNumericValue(value, cssValue) ||
ParseNamedSpaceValue(mPresentationData.mstyle, value, cssValue))
{
if (nsMathMLElement::ParseNumericValue(value, cssValue,
nsMathMLElement::
PARSE_ALLOW_UNITLESS)) {
nsCSSUnit unit = cssValue.GetUnit();
if (eCSSUnit_Number == unit)
mMaxSize = cssValue.GetFloatValue();
@ -556,20 +583,6 @@ nsMathMLmoFrame::ProcessOperatorData()
mMaxSize = float(CalcLength(presContext, mStyleContext, cssValue));
mFlags |= NS_MATHML_OPERATOR_MAXSIZE_ABSOLUTE;
}
if ((eCSSUnit_Number == unit) || (eCSSUnit_Percent == unit)) {
// see if the multiplicative inheritance should be from <mstyle>
GetAttribute(nsnull, mPresentationData.mstyle,
nsGkAtoms::maxsize_, value);
if (!value.IsEmpty()) {
if (ParseNumericValue(value, cssValue)) {
if (cssValue.IsLengthUnit()) {
mMaxSize *= float(CalcLength(presContext, mStyleContext, cssValue));
mFlags |= NS_MATHML_OPERATOR_MAXSIZE_ABSOLUTE;
}
}
}
}
}
}
}

View File

@ -23,6 +23,7 @@
* Roger B. Sidje <rbs@maths.uq.edu.au>
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
* Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation
* Frederic Wang <fred.wang@free.fr>
*
* 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"),
@ -106,7 +107,9 @@ nsMathMLmpaddedFrame::ProcessAttributes()
There is one exceptional element, <mpadded>, whose attributes cannot be
set with <mstyle>. When the attributes width, height and depth are specified
on an <mstyle> element, they apply only to the <mspace/> element. Similarly,
when lspace is set with <mstyle>, it applies only to the <mo> element.
when lspace is set with <mstyle>, it applies only to the <mo> element. To be
consistent, the voffset attribute of the mpadded element can not be set on
mstyle.
*/
// See if attributes are local, don't access mstyle !
@ -185,10 +188,6 @@ nsMathMLmpaddedFrame::ParseAttribute(nsString& aString,
else
aSign = NS_MATHML_SIGN_UNSPECIFIED;
// skip any space after the sign
if (i < stringLength && nsCRT::IsAsciiSpace(aString[i]))
i++;
// get the number
bool gotDot = false, gotPercent = false;
for (; i < stringLength; i++) {
@ -226,40 +225,24 @@ nsMathMLmpaddedFrame::ParseAttribute(nsString& aString,
return false;
}
// skip any space after the number
if (i < stringLength && nsCRT::IsAsciiSpace(aString[i]))
i++;
// see if this is a percentage-based value
if (i < stringLength && aString[i] == '%') {
i++;
gotPercent = true;
// skip any space after the '%' sign
if (i < stringLength && nsCRT::IsAsciiSpace(aString[i]))
i++;
}
// the remainder now should be a css-unit, or a pseudo-unit, or a named-space
aString.Right(unit, stringLength - i);
if (unit.IsEmpty()) {
// also cater for the edge case of "0" for which the unit is optional
if (gotPercent || !floatValue) {
if (gotPercent) {
// case ["+"|"-"] unsigned-number "%"
aCSSValue.SetPercentValue(floatValue / 100.0f);
aPseudoUnit = NS_MATHML_PSEUDO_UNIT_ITSELF;
return true;
} else {
// The REC does not allow the case ["+"|"-"] unsigned-number
}
/*
else {
// no explicit CSS unit and no explicit pseudo-unit...
// In this case, the MathML REC suggests taking ems for
// h-unit (width, lspace) or exs for v-unit (height, depth).
// Here, however, we explicitly request authors to specify
// the unit. This is more in line with the CSS REC (and
// it allows keeping the code simpler...)
}
*/
}
else if (unit.EqualsLiteral("width")) aPseudoUnit = NS_MATHML_PSEUDO_UNIT_WIDTH;
else if (unit.EqualsLiteral("height")) aPseudoUnit = NS_MATHML_PSEUDO_UNIT_HEIGHT;
@ -267,8 +250,9 @@ nsMathMLmpaddedFrame::ParseAttribute(nsString& aString,
else if (!gotPercent) { // percentage can only apply to a pseudo-unit
// see if the unit is a named-space
// XXX nsnull in ParseNamedSpacedValue()? don't access mstyle?
if (ParseNamedSpaceValue(nsnull, unit, aCSSValue)) {
if (nsMathMLElement::ParseNamedSpaceValue(unit, aCSSValue,
nsMathMLElement::
PARSE_ALLOW_NEGATIVE)) {
// re-scale properly, and we know that the unit of the named-space is 'em'
floatValue *= aCSSValue.GetFloatValue();
aCSSValue.SetFloatValue(floatValue, eCSSUnit_EM);
@ -277,8 +261,11 @@ nsMathMLmpaddedFrame::ParseAttribute(nsString& aString,
}
// see if the input was just a CSS value
// We use a specific flag to indicate that the call is made from mpadded.
// We are not supposed to have a unitless, percent, negative or namedspace
// value here.
number.Append(unit); // leave the sign out if it was there
if (ParseNumericValue(number, aCSSValue))
if (nsMathMLElement::ParseNumericValue(number, aCSSValue, 0))
return true;
}

View File

@ -21,6 +21,7 @@
*
* Contributor(s):
* Roger B. Sidje <rbs@maths.uq.edu.au>
* Frederic Wang <fred.wang@free.fr>
*
* 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"),
@ -71,51 +72,65 @@ nsMathMLmspaceFrame::IsLeaf() const
void
nsMathMLmspaceFrame::ProcessAttributes(nsPresContext* aPresContext)
{
/*
parse the attributes
width = number h-unit
height = number v-unit
depth = number v-unit
*/
nsAutoString value;
nsCSSValue cssValue;
// width
//
// "Specifies the desired width of the space."
//
// values: length
// default: 0em
//
// The default value is "0em", so unitless values can be ignored.
// <mspace/> is listed among MathML elements allowing negative spacing and
// the MathML test suite contains "Presentation/TokenElements/mspace/mspace2"
// as an example. Hence we allow negative values.
//
mWidth = 0;
GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::width,
value);
if (!value.IsEmpty()) {
if ((ParseNumericValue(value, cssValue) ||
ParseNamedSpaceValue(mPresentationData.mstyle, value, cssValue)) &&
cssValue.IsLengthUnit()) {
mWidth = CalcLength(aPresContext, mStyleContext, cssValue);
}
ParseNumericValue(value, &mWidth,
nsMathMLElement::PARSE_ALLOW_NEGATIVE,
aPresContext, mStyleContext);
}
// height
//
// "Specifies the desired height (above the baseline) of the space."
//
// values: length
// default: 0ex
//
// The default value is "0ex", so unitless values can be ignored.
// XXXfredw Should we forbid negative values? (bugs 411227, 716349)
//
mHeight = 0;
GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::height,
value);
if (!value.IsEmpty()) {
if ((ParseNumericValue(value, cssValue) ||
ParseNamedSpaceValue(mPresentationData.mstyle, value, cssValue)) &&
cssValue.IsLengthUnit()) {
mHeight = CalcLength(aPresContext, mStyleContext, cssValue);
}
ParseNumericValue(value, &mHeight,
nsMathMLElement::PARSE_ALLOW_NEGATIVE,
aPresContext, mStyleContext);
}
// depth
//
// "Specifies the desired depth (below the baseline) of the space."
//
// values: length
// default: 0ex
//
// The default value is "0ex", so unitless values can be ignored.
// XXXfredw Should we forbid negative values? (bugs 411227, 716349)
//
mDepth = 0;
GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::depth_,
value);
if (!value.IsEmpty()) {
if ((ParseNumericValue(value, cssValue) ||
ParseNamedSpaceValue(mPresentationData.mstyle, value, cssValue)) &&
cssValue.IsLengthUnit()) {
mDepth = CalcLength(aPresContext, mStyleContext, cssValue);
}
ParseNumericValue(value, &mDepth,
nsMathMLElement::PARSE_ALLOW_NEGATIVE,
aPresContext, mStyleContext);
}
}

View File

@ -23,6 +23,7 @@
* Roger B. Sidje <rbs@maths.uq.edu.au>
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
* Shyjan Mahamud <mahamud@cs.cmu.edu> (added TeX rendering rules)
* Frederic Wang <fred.wang@free.fr>
*
* 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"),
@ -89,16 +90,25 @@ nsMathMLmsubFrame::Place (nsRenderingContext& aRenderingContext,
// extra spacing after sup/subscript
nscoord scriptSpace = nsPresContext::CSSPointsToAppUnits(0.5f); // 0.5pt as in plain TeX
// check if the subscriptshift attribute is there
// subscriptshift
//
// "Specifies the minimum amount to shift the baseline of subscript down; the
// default is for the rendering agent to use its own positioning rules."
//
// values: length
// default: automatic
//
// We use 0 as the default value so unitless values can be ignored.
// XXXfredw Should we forbid negative values? (bug 411227)
//
nscoord subScriptShift = 0;
nsAutoString value;
GetAttribute(mContent, mPresentationData.mstyle,
nsGkAtoms::subscriptshift_, value);
if (!value.IsEmpty()) {
nsCSSValue cssValue;
if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) {
subScriptShift = CalcLength(PresContext(), mStyleContext, cssValue);
}
ParseNumericValue(value, &subScriptShift,
nsMathMLElement::PARSE_ALLOW_NEGATIVE,
PresContext(), mStyleContext);
}
return nsMathMLmsubFrame::PlaceSubScript(PresContext(),

View File

@ -23,6 +23,7 @@
* Roger B. Sidje <rbs@maths.uq.edu.au>
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
* Shyjan Mahamud <mahamud@cs.cmu.edu> (added TeX rendering rules)
* Frederic Wang <fred.wang@free.fr>
*
* 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"),
@ -95,26 +96,44 @@ nsMathMLmsubsupFrame::Place(nsRenderingContext& aRenderingContext,
// extra spacing between base and sup/subscript
nscoord scriptSpace = 0;
// check if the subscriptshift attribute is there
// subscriptshift
//
// "Specifies the minimum amount to shift the baseline of subscript down; the
// default is for the rendering agent to use its own positioning rules."
//
// values: length
// default: automatic
//
// We use 0 as the default value so unitless values can be ignored.
// XXXfredw Should we forbid negative values? (bug 411227)
//
nsAutoString value;
nscoord subScriptShift = 0;
GetAttribute(mContent, mPresentationData.mstyle,
nsGkAtoms::subscriptshift_, value);
if (!value.IsEmpty()) {
nsCSSValue cssValue;
if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) {
subScriptShift = CalcLength(PresContext(), mStyleContext, cssValue);
}
ParseNumericValue(value, &subScriptShift,
nsMathMLElement::PARSE_ALLOW_NEGATIVE,
PresContext(), mStyleContext);
}
// check if the superscriptshift attribute is there
// superscriptshift
//
// "Specifies the minimum amount to shift the baseline of superscript up; the
// default is for the rendering agent to use its own positioning rules."
//
// values: length
// default: automatic
//
// We use 0 as the default value so unitless values can be ignored.
// XXXfredw Should we forbid negative values? (bug 411227)
//
nscoord supScriptShift = 0;
GetAttribute(mContent, mPresentationData.mstyle,
nsGkAtoms::superscriptshift_, value);
if (!value.IsEmpty()) {
nsCSSValue cssValue;
if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) {
supScriptShift = CalcLength(PresContext(), mStyleContext, cssValue);
}
ParseNumericValue(value, &supScriptShift,
nsMathMLElement::PARSE_ALLOW_NEGATIVE,
PresContext(), mStyleContext);
}
return nsMathMLmsubsupFrame::PlaceSubSupScript(PresContext(),

View File

@ -23,6 +23,7 @@
* Roger B. Sidje <rbs@maths.uq.edu.au>
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
* Shyjan Mahamud <mahamud@cs.cmu.edu> (added TeX rendering rules)
* Frederic Wang <fred.wang@free.fr>
*
* 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"),
@ -89,16 +90,25 @@ nsMathMLmsupFrame::Place(nsRenderingContext& aRenderingContext,
// extra spacing after sup/subscript
nscoord scriptSpace = nsPresContext::CSSPointsToAppUnits(0.5f); // 0.5pt as in plain TeX
// check if the superscriptshift attribute is there
// superscriptshift
//
// "Specifies the minimum amount to shift the baseline of superscript up; the
// default is for the rendering agent to use its own positioning rules."
//
// values: length
// default: automatic
//
// We use 0 as the default value so unitless values can be ignored.
// XXXfredw Should we forbid negative values? (bug 411227)
//
nsAutoString value;
nscoord supScriptShift = 0;
GetAttribute(mContent, mPresentationData.mstyle,
nsGkAtoms::superscriptshift_, value);
if (!value.IsEmpty()) {
nsCSSValue cssValue;
if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) {
supScriptShift = CalcLength(PresContext(), mStyleContext, cssValue);
}
ParseNumericValue(value, &supScriptShift,
nsMathMLElement::PARSE_ALLOW_NEGATIVE,
PresContext(), mStyleContext);
}
return nsMathMLmsupFrame::PlaceSuperScript(PresContext(),