зеркало из https://github.com/mozilla/gecko-dev.git
[MathML] Added support for CSS units on numeric attributes and updated code to make use of the support
This commit is contained in:
Родитель
cc0d62ff60
Коммит
bdab93b4ec
|
@ -122,6 +122,164 @@ nsMathMLContainerFrame::IsOnlyWhitespace(nsIFrame* aFrame)
|
|||
return rv;
|
||||
}
|
||||
|
||||
// helper to get an attribute from the content or the surrounding <mstyle>
|
||||
nsresult
|
||||
nsMathMLContainerFrame::GetAttribute(nsIContent* aContent,
|
||||
nsIFrame* aMathMLmstyleFrame,
|
||||
nsIAtom* aAttributeAtom,
|
||||
nsString& aValue)
|
||||
{
|
||||
// see if we can get the attribute from the content
|
||||
if (aContent) {
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE ==
|
||||
aContent->GetAttribute(kNameSpaceID_None, aAttributeAtom, aValue))
|
||||
return NS_CONTENT_ATTR_HAS_VALUE;
|
||||
}
|
||||
|
||||
// see if we can get the attribute from the mstyle frame
|
||||
if (aMathMLmstyleFrame) {
|
||||
nsCOMPtr<nsIContent> mstyleContent;
|
||||
aMathMLmstyleFrame->GetContent(getter_AddRefs(mstyleContent));
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE ==
|
||||
mstyleContent->GetAttribute(kNameSpaceID_None, aAttributeAtom, aValue))
|
||||
return NS_CONTENT_ATTR_HAS_VALUE;
|
||||
}
|
||||
|
||||
return NS_CONTENT_ATTR_NOT_THERE;
|
||||
}
|
||||
|
||||
// ================
|
||||
// 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]
|
||||
*/
|
||||
|
||||
// Adapted from nsCSSScanner.cpp & CSSParser.cpp
|
||||
PRBool
|
||||
nsMathMLContainerFrame::ParseNumericValue(const nsString& aString,
|
||||
nsCSSValue& aCSSValue)
|
||||
{
|
||||
PRInt32 stringLength = aString.Length();
|
||||
|
||||
if (!stringLength) return PR_FALSE;
|
||||
|
||||
nsAutoString number = aString;
|
||||
number.SetLength(0);
|
||||
|
||||
nsAutoString unit = aString;
|
||||
unit.SetLength(0);
|
||||
|
||||
// Gather up characters that make up the number
|
||||
PRBool gotDot = PR_FALSE;
|
||||
PRUnichar c;
|
||||
for (PRInt32 i = 0; i < stringLength; i++) {
|
||||
c = aString[i];
|
||||
if (gotDot && c == '.')
|
||||
return PR_FALSE; // two dots encountered
|
||||
else if (c == '.')
|
||||
gotDot = PR_TRUE;
|
||||
else if (!nsString::IsDigit(c)) {
|
||||
aString.Right(unit, stringLength - i);
|
||||
break;
|
||||
}
|
||||
number.Append(PRUnichar(c));
|
||||
}
|
||||
|
||||
#if 0
|
||||
char s1[50], s2[50], s3[50];
|
||||
aString.ToCString(s1, 50);
|
||||
number.ToCString(s2, 50);
|
||||
unit.ToCString(s3, 50);
|
||||
printf("String:%s, Number:%s, Unit:%s\n", s1, s2, s3);
|
||||
#endif
|
||||
|
||||
// Convert number to floating point
|
||||
PRInt32 errorCode;
|
||||
float floatValue = number.ToFloat(&errorCode);
|
||||
if (NS_FAILED(errorCode)) return PR_FALSE;
|
||||
|
||||
nsCSSUnit cssUnit;
|
||||
if (0 == unit.Length()) {
|
||||
cssUnit = eCSSUnit_Number; // no explicit unit, this is a number that will act as a multiplier
|
||||
}
|
||||
else if (unit == "%") {
|
||||
floatValue = floatValue / 100.0f;
|
||||
aCSSValue.SetPercentValue(floatValue);
|
||||
return PR_TRUE;
|
||||
}
|
||||
else if (unit == "em") cssUnit = eCSSUnit_EM;
|
||||
else if (unit == "ex") cssUnit = eCSSUnit_XHeight;
|
||||
else if (unit == "px") cssUnit = eCSSUnit_Pixel;
|
||||
else if (unit == "in") cssUnit = eCSSUnit_Inch;
|
||||
else if (unit == "cm") cssUnit = eCSSUnit_Centimeter;
|
||||
else if (unit == "mm") cssUnit = eCSSUnit_Millimeter;
|
||||
else if (unit == "pt") cssUnit = eCSSUnit_Point;
|
||||
else if (unit == "pc") cssUnit = eCSSUnit_Pica;
|
||||
else // unexpected unit
|
||||
return PR_FALSE;
|
||||
|
||||
aCSSValue.SetFloatValue(floatValue, cssUnit);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// Adapted from nsCSSStyleRule.cpp
|
||||
nscoord
|
||||
nsMathMLContainerFrame::CalcLength(nsIPresContext* aPresContext,
|
||||
nsIStyleContext* aStyleContext,
|
||||
const nsCSSValue& aValue)
|
||||
{
|
||||
NS_ASSERTION(aValue.IsLengthUnit(), "not a length unit");
|
||||
|
||||
if (aValue.IsFixedLengthUnit()) {
|
||||
return aValue.GetLengthTwips();
|
||||
}
|
||||
|
||||
nsCSSUnit unit = aValue.GetUnit();
|
||||
|
||||
if (eCSSUnit_Pixel == unit) {
|
||||
float p2t;
|
||||
aPresContext->GetScaledPixelsToTwips(&p2t);
|
||||
return NSFloatPixelsToTwips(aValue.GetFloatValue(), p2t);
|
||||
}
|
||||
else if (eCSSUnit_EM == unit) {
|
||||
nsStyleFont font;
|
||||
aStyleContext->GetStyle(eStyleStruct_Font, font);
|
||||
return NSToCoordRound(aValue.GetFloatValue() * (float)font.mFont.size);
|
||||
}
|
||||
else if (eCSSUnit_XHeight == unit) {
|
||||
nscoord xHeight;
|
||||
nsStyleFont font;
|
||||
aStyleContext->GetStyle(eStyleStruct_Font, font);
|
||||
nsCOMPtr<nsIFontMetrics> fm;
|
||||
aPresContext->GetMetricsFor(font.mFont, getter_AddRefs(fm));
|
||||
fm->GetXHeight(xHeight);
|
||||
return NSToCoordRound(aValue.GetFloatValue() * (float)xHeight);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -------------------------
|
||||
|
||||
void
|
||||
nsMathMLContainerFrame::ReflowEmptyChild(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame)
|
||||
|
@ -610,26 +768,29 @@ nsMathMLContainerFrame::InsertScriptLevelStyleContext(nsIPresContext* aPresConte
|
|||
// smaller-font-size algorithm of the style system
|
||||
PRInt32 scriptminsize = NSIntPointsToTwips(8);
|
||||
|
||||
// see if the scriptminsize attribute is on <mstyle> that wraps us
|
||||
// see if there is a scriptminsize attribute on a <mstyle> that wraps us
|
||||
nsAutoString value;
|
||||
nsIFrame* mstyleFrame = mPresentationData.mstyle;
|
||||
if (mstyleFrame) {
|
||||
nsCOMPtr<nsIContent> mstyleContent;
|
||||
mstyleFrame->GetContent(getter_AddRefs(mstyleContent));
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mstyleContent->GetAttribute(kNameSpaceID_None,
|
||||
nsMathMLAtoms::scriptminsize_, value))
|
||||
{
|
||||
PRInt32 errorCode;
|
||||
PRInt32 userValue = value.ToInteger(&errorCode);
|
||||
if (NS_SUCCEEDED(errorCode)) {
|
||||
// assume unit is point
|
||||
// XXX need consistent, default unit throughout the code
|
||||
scriptminsize = NSIntPointsToTwips(userValue);
|
||||
}
|
||||
else {
|
||||
// XXX TODO: try to see if it is a h/v-unit like 1ex, 2px, 1em
|
||||
}
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE ==
|
||||
GetAttribute(nsnull, mPresentationData.mstyle,
|
||||
nsMathMLAtoms::scriptminsize_, value))
|
||||
{
|
||||
nsCSSValue cssValue;
|
||||
if (ParseNumericValue(value, 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(aPresContext, mStyleContext, cssValue);
|
||||
}
|
||||
#ifdef NS_DEBUG
|
||||
else {
|
||||
char str[50];
|
||||
value.ToCString(str, 50);
|
||||
printf("Invalid attribute scriptminsize=%s\n", str);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// get Nav's magic font scaler
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#include "nsIMathMLFrame.h"
|
||||
#include "nsMathMLParts.h"
|
||||
|
||||
#include "nsCSSValue.h"
|
||||
|
||||
/*
|
||||
* Base class for MathML container frames. It acts like an inferred
|
||||
* mrow. By default, this frame uses its Reflow() method to lay its
|
||||
|
@ -256,6 +258,27 @@ public:
|
|||
nsHTMLReflowMetrics& aReflowMetrics,
|
||||
nsBoundingMetrics& aBoundingMetrics);
|
||||
|
||||
// helper to check if a content has an attribute. If content is nsnull or if
|
||||
// the attribute is not there, check if the attribute is on the mstyle frame.
|
||||
// @return NS_CONTENT_ATTR_HAS_VALUE --if attribute is there
|
||||
// NS_CONTENT_ATTR_NOT_THERE --if attribute is not there
|
||||
static nsresult
|
||||
GetAttribute(nsIContent* aContent,
|
||||
nsIFrame* aMathMLmstyleFrame,
|
||||
nsIAtom* aAttributeAtom,
|
||||
nsString& aValue);
|
||||
|
||||
// utilities to parse and retrieve numeric values in CSS units
|
||||
// All values are stored in twips.
|
||||
static PRBool
|
||||
ParseNumericValue(const nsString& aString,
|
||||
nsCSSValue& aCSSValue);
|
||||
|
||||
static nscoord
|
||||
CalcLength(nsIPresContext* aPresContext,
|
||||
nsIStyleContext* aStyleContext,
|
||||
const nsCSSValue& aValue);
|
||||
|
||||
// helper methods for getting sup/subdrop's from a child
|
||||
static void
|
||||
GetSubDropFromChild (nsIPresContext* aPresContext,
|
||||
|
@ -309,23 +332,6 @@ public:
|
|||
}
|
||||
|
||||
// these are TeX specific params not found in ordinary fonts
|
||||
#if 0
|
||||
static void
|
||||
GetSubDrop (nsIFontMetrics *fm, nscoord& aSubDrop)
|
||||
{
|
||||
nscoord xHeight;
|
||||
fm->GetXHeight (xHeight);
|
||||
aSubDrop = NSToCoordRound(0.3f * xHeight);
|
||||
}
|
||||
|
||||
static void
|
||||
GetSupDrop (nsIFontMetrics *fm, nscoord& aSupDrop)
|
||||
{
|
||||
nscoord xHeight;
|
||||
fm->GetXHeight (xHeight);
|
||||
aSupDrop = NSToCoordRound(0.3f * xHeight);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
GetSubDrop (nsIFontMetrics *fm, nscoord& aSubDrop)
|
||||
|
|
|
@ -3,19 +3,19 @@
|
|||
* 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 Project.
|
||||
*
|
||||
* The Initial Developer of the Original Code is The University Of
|
||||
*
|
||||
* The Initial Developer of the Original Code is The University Of
|
||||
* Queensland. Portions created by The University Of Queensland are
|
||||
* Copyright (C) 1999 The University Of Queensland. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Contributor(s):
|
||||
* Roger B. Sidje <rbs@maths.uq.edu.au>
|
||||
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
|
||||
*/
|
||||
|
@ -80,39 +80,51 @@ nsMathMLmfracFrame::Init(nsIPresContext* aPresContext,
|
|||
return rv;
|
||||
}
|
||||
|
||||
nscoord aLineThickness = DEFAULT_FRACTION_LINE_THICKNESS;
|
||||
nsAutoString value;
|
||||
|
||||
// see if the linethickness attribute is there
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
|
||||
float p2t;
|
||||
aPresContext->GetScaledPixelsToTwips(&p2t);
|
||||
nscoord onePixel = NSIntPixelsToTwips(1, p2t);
|
||||
|
||||
nscoord defaultThickness = onePixel * DEFAULT_FRACTION_LINE_THICKNESS;
|
||||
|
||||
mLineThickness = defaultThickness;
|
||||
|
||||
// see if the linethickness attribute is there
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE ==
|
||||
GetAttribute(mContent, mPresentationData.mstyle,
|
||||
nsMathMLAtoms::linethickness_, value))
|
||||
{
|
||||
if (value == "thin")
|
||||
aLineThickness = THIN_FRACTION_LINE_THICKNESS;
|
||||
mLineThickness = onePixel * THIN_FRACTION_LINE_THICKNESS;
|
||||
else if (value == "medium")
|
||||
aLineThickness = MEDIUM_FRACTION_LINE_THICKNESS;
|
||||
mLineThickness = onePixel * MEDIUM_FRACTION_LINE_THICKNESS;
|
||||
else if (value == "thick")
|
||||
aLineThickness = THICK_FRACTION_LINE_THICKNESS;
|
||||
else {
|
||||
PRInt32 aErrorCode;
|
||||
PRInt32 aMultiplier = value.ToInteger(&aErrorCode);
|
||||
if (NS_SUCCEEDED(aErrorCode))
|
||||
aLineThickness = aMultiplier * DEFAULT_FRACTION_LINE_THICKNESS;
|
||||
else {
|
||||
// XXX TODO: try to see if it is a h/v-unit like 1ex, 2px, 1em
|
||||
// see also nsUnitConversion.h
|
||||
mLineThickness = onePixel * THICK_FRACTION_LINE_THICKNESS;
|
||||
else { // see if it is a plain number, or a percentage, or a h/v-unit like 1ex, 2px, 1em
|
||||
nsCSSValue cssValue;
|
||||
if (ParseNumericValue(value, cssValue)) {
|
||||
nsCSSUnit unit = cssValue.GetUnit();
|
||||
if (eCSSUnit_Number == unit)
|
||||
mLineThickness = nscoord(float(defaultThickness) * cssValue.GetFloatValue());
|
||||
else if (eCSSUnit_Percent == unit)
|
||||
mLineThickness = nscoord(float(defaultThickness) * cssValue.GetPercentValue());
|
||||
else if (eCSSUnit_Null != unit)
|
||||
mLineThickness = CalcLength(aPresContext, mStyleContext, cssValue);
|
||||
}
|
||||
#ifdef NS_DEBUG
|
||||
else {
|
||||
char str[50];
|
||||
value.ToCString(str, 50);
|
||||
printf("Invalid attribute linethickness=%s\n", str);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// mLineThickness = (aLineThickness > MAX_FRACTION_LINE_THICKNESS) ?
|
||||
// MAX_FRACTION_LINE_THICKNESS : aLineThickness;
|
||||
|
||||
mLineThickness = aLineThickness;
|
||||
mLineOrigin.x = 0;
|
||||
mLineOrigin.y = 0;
|
||||
mLineOrigin.y = 0;
|
||||
|
||||
// TODO: other attributes...
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -123,10 +135,10 @@ nsMathMLmfracFrame::Paint(nsIPresContext* aPresContext,
|
|||
nsFramePaintLayer aWhichLayer)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
|
||||
/////////////
|
||||
// paint the numerator and denominator
|
||||
rv = nsMathMLContainerFrame::Paint(aPresContext, aRenderingContext,
|
||||
rv = nsMathMLContainerFrame::Paint(aPresContext, aRenderingContext,
|
||||
aDirtyRect, aWhichLayer);
|
||||
|
||||
if (NS_FRAME_PAINT_LAYER_FOREGROUND != aWhichLayer) {
|
||||
|
@ -136,24 +148,22 @@ nsMathMLmfracFrame::Paint(nsIPresContext* aPresContext,
|
|||
////////////
|
||||
// paint the fraction line
|
||||
if (NS_SUCCEEDED(rv) && 0 < mLineThickness) {
|
||||
float p2t;
|
||||
aPresContext->GetScaledPixelsToTwips(&p2t);
|
||||
nscoord thickness = NSIntPixelsToTwips(mLineThickness, p2t);
|
||||
|
||||
/*
|
||||
// line looking like <hr noshade>
|
||||
const nsStyleColor* color;
|
||||
nscolor colors[2];
|
||||
color = nsStyleUtil::FindNonTransparentBackground(mStyleContext);
|
||||
NS_Get3DColors(colors, color->mBackgroundColor);
|
||||
aRenderingContext.SetColor(colors[0]);
|
||||
nscolor colors[2];
|
||||
color = nsStyleUtil::FindNonTransparentBackground(mStyleContext);
|
||||
NS_Get3DColors(colors, color->mBackgroundColor);
|
||||
aRenderingContext.SetColor(colors[0]);
|
||||
*/
|
||||
// solid line with the current text color
|
||||
const nsStyleColor* color =
|
||||
(const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color);
|
||||
aRenderingContext.SetColor(color->mColor);
|
||||
|
||||
// draw the line
|
||||
aRenderingContext.FillRect(mLineOrigin.x, mLineOrigin.y, mRect.width, thickness);
|
||||
// draw the line
|
||||
aRenderingContext.FillRect(mLineOrigin.x, mLineOrigin.y, mRect.width, mLineThickness);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -167,19 +177,19 @@ nsMathMLmfracFrame::Reflow(nsIPresContext* aPresContext,
|
|||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsReflowStatus childStatus;
|
||||
// ask our children to compute their bounding metrics
|
||||
// ask our children to compute their bounding metrics
|
||||
nsHTMLReflowMetrics childDesiredSize(aDesiredSize.maxElementSize,
|
||||
aDesiredSize.mFlags | NS_REFLOW_CALC_BOUNDING_METRICS);
|
||||
nsSize availSize(aReflowState.mComputedWidth, aReflowState.mComputedHeight);
|
||||
|
||||
//////////////////
|
||||
// Reflow Children
|
||||
|
||||
|
||||
nscoord count = 0;
|
||||
nsRect rect[2];
|
||||
nsIFrame* child[2];
|
||||
nsIFrame* childFrame = mFrames.FirstChild();
|
||||
while (nsnull != childFrame)
|
||||
nsIFrame* childFrame = mFrames.FirstChild();
|
||||
while (nsnull != childFrame)
|
||||
{
|
||||
//////////////
|
||||
// WHITESPACE: don't forget that whitespace doesn't count in MathML!
|
||||
|
@ -195,10 +205,10 @@ nsMathMLmfracFrame::Reflow(nsIPresContext* aPresContext,
|
|||
return rv;
|
||||
}
|
||||
|
||||
child[count] = childFrame;
|
||||
child[count] = childFrame;
|
||||
rect[count].width = childDesiredSize.width;
|
||||
rect[count].height = childDesiredSize.height;
|
||||
count++;
|
||||
count++;
|
||||
}
|
||||
// else { invalid markup... }
|
||||
|
||||
|
@ -207,9 +217,9 @@ nsMathMLmfracFrame::Reflow(nsIPresContext* aPresContext,
|
|||
}
|
||||
|
||||
//////////////////
|
||||
// Place Children
|
||||
|
||||
// Get the <strike> line and center the fraction bar with the <strike> line.
|
||||
// Place Children
|
||||
|
||||
// Get the <strike> line and center the fraction bar with the <strike> line.
|
||||
nscoord strikeOffset, strikeThickness;
|
||||
nsCOMPtr<nsIFontMetrics> fm;
|
||||
const nsStyleFont* aFont =
|
||||
|
@ -219,16 +229,12 @@ nsMathMLmfracFrame::Reflow(nsIPresContext* aPresContext,
|
|||
|
||||
// Take care of mLineThickness
|
||||
float p2t;
|
||||
nscoord Thickspace, halfThickspace;
|
||||
nscoord halfThickspace;
|
||||
aPresContext->GetScaledPixelsToTwips(&p2t);
|
||||
if (mLineThickness <= 1) {
|
||||
Thickspace = 0;
|
||||
halfThickspace = 0;
|
||||
}
|
||||
else {
|
||||
Thickspace = NSIntPixelsToTwips(mLineThickness-1, p2t);
|
||||
halfThickspace = Thickspace/2; // distance from the middle of the axis
|
||||
}
|
||||
nscoord onePixel = NSIntPixelsToTwips(1, p2t);
|
||||
|
||||
// distance from the middle of the axis
|
||||
halfThickspace = (mLineThickness > onePixel)? mLineThickness/2 : 0;
|
||||
|
||||
aDesiredSize.width = PR_MAX(rect[0].width, rect[1].width);
|
||||
aDesiredSize.ascent = rect[0].height + strikeOffset + halfThickspace;
|
||||
|
@ -248,7 +254,7 @@ nsMathMLmfracFrame::Reflow(nsIPresContext* aPresContext,
|
|||
childSize.height = rect[i].height;
|
||||
FinishReflowChild(child[i], aPresContext, childSize, rect[i].x, rect[i].y, 0);
|
||||
}
|
||||
SetLineOrigin(nsPoint(0,rect[0].height)); // position the fraction bar
|
||||
SetLineOrigin(nsPoint(0,rect[0].height)); // position the fraction bar
|
||||
|
||||
if (nsnull != aDesiredSize.maxElementSize) {
|
||||
aDesiredSize.maxElementSize->width = aDesiredSize.width;
|
||||
|
|
|
@ -50,7 +50,7 @@ The linethickness attribute indicates the thickness of the horizontal
|
|||
"fraction bar", or "rule", typically used to render fractions. A fraction
|
||||
with linethickness="0" renders without the bar, and might be used within
|
||||
binomial coefficients. A linethickness greater than one might be used with
|
||||
nested fractions. These cases are shown below:
|
||||
nested fractions.
|
||||
|
||||
In general, the value of linethickness can be a number, as a multiplier
|
||||
of the default thickness of the fraction bar (the default thickness is
|
||||
|
@ -63,26 +63,9 @@ The <mfrac> element sets displaystyle to "false", or if it was already
|
|||
false increments scriptlevel by 1, within numerator and denominator.
|
||||
These attributes are inherited by every element from its rendering
|
||||
environment, but can be set explicitly only on the <mstyle>
|
||||
element. (See Section 3.3.4.)
|
||||
element.
|
||||
*/
|
||||
|
||||
/*
|
||||
TODO:
|
||||
Units...
|
||||
- CalcLength(..) in nsCSSStyleRule.cpp is where CSS units are implemented.
|
||||
How to use that for linethickness and, in general, how to factor the use
|
||||
of units in the MathML world?
|
||||
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
|
||||
*/
|
||||
|
||||
// default fraction line thickness in pixels
|
||||
#define DEFAULT_FRACTION_LINE_THICKNESS 1
|
||||
|
@ -91,9 +74,6 @@ pc picas (1 pica = 12 points)
|
|||
#define MEDIUM_FRACTION_LINE_THICKNESS 2
|
||||
#define THICK_FRACTION_LINE_THICKNESS 4
|
||||
|
||||
// use an upper bound just in case someone set a too high value? why bother?
|
||||
// #define MAX_FRACTION_LINE_THICKNESS 5
|
||||
|
||||
class nsMathMLmfracFrame : public nsMathMLContainerFrame {
|
||||
public:
|
||||
friend nsresult NS_NewMathMLmfracFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
|
|
@ -77,30 +77,25 @@ nsMathMLmmultiscriptsFrame::Init(nsIPresContext* aPresContext,
|
|||
nsresult rv = nsMathMLContainerFrame::Init
|
||||
(aPresContext, aContent, aParent, aContext, aPrevInFlow);
|
||||
|
||||
mSubScriptShiftFactor = 0.0f;
|
||||
mSupScriptShiftFactor = 0.0f;
|
||||
mSubScriptShift = 0;
|
||||
mSupScriptShift = 0;
|
||||
mScriptSpace = NSFloatPointsToTwips(0.5f); // 0.5pt as in plain TeX
|
||||
|
||||
// check for subscriptshift and superscriptshift attribute in ex units
|
||||
// check if the subscriptshift attribute is there
|
||||
nsAutoString value;
|
||||
mSubUserSetFlag = mSupUserSetFlag = PR_FALSE;
|
||||
mSubScriptShiftFactor = mSubScriptShiftFactor = 0.0f;
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute
|
||||
(kNameSpaceID_None, nsMathMLAtoms::subscriptshift_, value)) {
|
||||
PRInt32 aErrorCode;
|
||||
float aUserValue = value.ToFloat(&aErrorCode);
|
||||
if (NS_SUCCEEDED(aErrorCode)) {
|
||||
mSubUserSetFlag = PR_TRUE;
|
||||
mSubScriptShiftFactor = aUserValue;
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
|
||||
nsMathMLAtoms::subscriptshift_, value)) {
|
||||
nsCSSValue cssValue;
|
||||
if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) {
|
||||
mSubScriptShift = CalcLength(aPresContext, mStyleContext, cssValue);
|
||||
}
|
||||
}
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute
|
||||
(kNameSpaceID_None, nsMathMLAtoms::superscriptshift_, value)) {
|
||||
PRInt32 aErrorCode;
|
||||
float aUserValue = value.ToFloat(&aErrorCode);
|
||||
if (NS_SUCCEEDED(aErrorCode)) {
|
||||
mSupUserSetFlag = PR_TRUE;
|
||||
mSupScriptShiftFactor = aUserValue;
|
||||
// check if the superscriptshift attribute is there
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
|
||||
nsMathMLAtoms::superscriptshift_, value)) {
|
||||
nsCSSValue cssValue;
|
||||
if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) {
|
||||
mSupScriptShift = CalcLength(aPresContext, mStyleContext, cssValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,10 +144,10 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
|
|||
|
||||
// Get aSubScriptShift{1,2} default from font
|
||||
GetSubScriptShifts (fm, aSubScriptShift1, aSubScriptShift2);
|
||||
if (mSubUserSetFlag) {
|
||||
if (0 < mSubScriptShift) {
|
||||
// the user has set the subscriptshift attribute
|
||||
float aFactor = ((float) aSubScriptShift2) / aSubScriptShift1;
|
||||
aSubScriptShift1 = NSToCoordRound(mSubScriptShiftFactor * xHeight);
|
||||
aSubScriptShift1 = PR_MAX(aSubScriptShift1, mSubScriptShift);
|
||||
aSubScriptShift2 = NSToCoordRound(aFactor * aSubScriptShift1);
|
||||
}
|
||||
// the font dependent shift
|
||||
|
@ -170,11 +165,11 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
|
|||
nscoord aSupScriptShift1, aSupScriptShift2, aSupScriptShift3;
|
||||
// Set aSupScriptShift{1,2,3} default from font
|
||||
GetSupScriptShifts (fm, aSupScriptShift1, aSupScriptShift2, aSupScriptShift3);
|
||||
if (mSupUserSetFlag) {
|
||||
if (0 < mSupScriptShift) {
|
||||
// the user has set the superscriptshift attribute
|
||||
float aFactor2 = ((float) aSupScriptShift2) / aSupScriptShift1;
|
||||
float aFactor3 = ((float) aSupScriptShift3) / aSupScriptShift1;
|
||||
aSupScriptShift1 = NSToCoordRound(mSupScriptShiftFactor * xHeight);
|
||||
aSupScriptShift1 = PR_MAX(aSupScriptShift1, mSupScriptShift);
|
||||
aSupScriptShift2 = NSToCoordRound(aFactor2 * aSupScriptShift1);
|
||||
aSupScriptShift3 = NSToCoordRound(aFactor3 * aSupScriptShift1);
|
||||
}
|
||||
|
|
|
@ -72,8 +72,8 @@ protected:
|
|||
private:
|
||||
nscoord mScriptSpace; // scriptspace from TeX for extra spacing after sup/subscript
|
||||
// = 0.5pt in plain TeX
|
||||
float mSubScriptShiftFactor, mSupScriptShiftFactor;
|
||||
PRBool mSubUserSetFlag, mSupUserSetFlag;
|
||||
nscoord mSubScriptShift;
|
||||
nscoord mSupScriptShift;
|
||||
};
|
||||
|
||||
#endif /* nsMathMLmmultiscriptsFrame_h___ */
|
||||
|
|
|
@ -156,6 +156,8 @@ nsMathMLmoFrame::Init(nsIPresContext* aPresContext,
|
|||
mFlags = 0;
|
||||
mLeftSpace = 0.0f; // .27777f;
|
||||
mRightSpace = 0.0f; // .27777f;
|
||||
mMinSize = float(NS_UNCONSTRAINEDSIZE);
|
||||
mMaxSize = float(NS_UNCONSTRAINEDSIZE);
|
||||
|
||||
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
|
||||
return rv;
|
||||
|
@ -222,7 +224,7 @@ nsMathMLmoFrame::SetInitialChildList(nsIPresContext* aPresContext,
|
|||
PRBool movablelimitsAttribute = PR_FALSE;
|
||||
|
||||
// see if the accent attribute is there
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
|
||||
nsMathMLAtoms::accent_, value))
|
||||
{
|
||||
accentAttribute = PR_TRUE;
|
||||
|
@ -233,7 +235,7 @@ nsMathMLmoFrame::SetInitialChildList(nsIPresContext* aPresContext,
|
|||
}
|
||||
|
||||
// see if the movablelimits attribute is there
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
|
||||
nsMathMLAtoms::movablelimits_, value))
|
||||
{
|
||||
movablelimitsAttribute = PR_TRUE;
|
||||
|
@ -278,7 +280,7 @@ nsMathMLmoFrame::SetInitialChildList(nsIPresContext* aPresContext,
|
|||
}
|
||||
|
||||
void
|
||||
nsMathMLmoFrame::InitData()
|
||||
nsMathMLmoFrame::InitData(nsIPresContext* aPresContext)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
mFlags = 0;
|
||||
|
@ -289,7 +291,7 @@ nsMathMLmoFrame::InitData()
|
|||
nsIMathMLFrame* aMathMLFrame = nsnull;
|
||||
nsIFrame* embellishAncestor = nsnull;
|
||||
PRBool hasEmbellishAncestor = PR_FALSE;
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
|
||||
nsMathMLAtoms::form_, value)) {
|
||||
if (value == "prefix")
|
||||
aForm = NS_MATHML_OPERATOR_FORM_PREFIX;
|
||||
|
@ -392,8 +394,6 @@ nsMathMLmoFrame::InitData()
|
|||
mRightSpace /= 2.0f;
|
||||
}
|
||||
|
||||
// XXX Factor all this in nsMathMLAttributes.cpp
|
||||
|
||||
// Now see if there are user-defined attributes that override the dictionary.
|
||||
// XXX If an attribute can be forced to be true when it is false in the
|
||||
// dictionary, then the following code has to change...
|
||||
|
@ -403,51 +403,108 @@ nsMathMLmoFrame::InitData()
|
|||
|
||||
nsAutoString kfalse("false"), ktrue("true");
|
||||
if (NS_MATHML_OPERATOR_IS_STRETCHY(mFlags)) {
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
|
||||
nsMathMLAtoms::stretchy_, value) && value == kfalse)
|
||||
mFlags &= ~NS_MATHML_OPERATOR_STRETCHY;
|
||||
}
|
||||
if (NS_MATHML_OPERATOR_IS_FENCE(mFlags)) {
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
|
||||
nsMathMLAtoms::fence_, value) && value == kfalse)
|
||||
mFlags &= ~NS_MATHML_OPERATOR_FENCE;
|
||||
}
|
||||
if (NS_MATHML_OPERATOR_IS_ACCENT(mFlags)) {
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
|
||||
nsMathMLAtoms::accent_, value) && value == kfalse)
|
||||
mFlags &= ~NS_MATHML_OPERATOR_ACCENT;
|
||||
}
|
||||
if (NS_MATHML_OPERATOR_IS_LARGEOP(mFlags)) {
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
|
||||
nsMathMLAtoms::largeop_, value) && value == kfalse)
|
||||
mFlags &= ~NS_MATHML_OPERATOR_LARGEOP;
|
||||
}
|
||||
if (NS_MATHML_OPERATOR_IS_SEPARATOR(mFlags)) {
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
|
||||
nsMathMLAtoms::separator_, value) && value == kfalse)
|
||||
mFlags &= ~NS_MATHML_OPERATOR_SEPARATOR;
|
||||
}
|
||||
if (NS_MATHML_OPERATOR_IS_MOVABLELIMITS(mFlags)) {
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
|
||||
nsMathMLAtoms::movablelimits_, value) && value == kfalse)
|
||||
mFlags &= ~NS_MATHML_OPERATOR_MOVABLELIMITS;
|
||||
}
|
||||
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
|
||||
nsMathMLAtoms::symmetric_, value)) {
|
||||
if (value == ktrue) mFlags |= NS_MATHML_OPERATOR_SYMMETRIC;
|
||||
if (value == kfalse) mFlags &= ~NS_MATHML_OPERATOR_SYMMETRIC;
|
||||
}
|
||||
|
||||
// TODO: add also lspace and rspace, minsize, maxsize, later ...
|
||||
|
||||
// If we are an accent without explicit lspace="." or rspace=".",
|
||||
// ignore our default left/right space
|
||||
if (NS_MATHML_EMBELLISH_IS_ACCENT(mEmbellishData.flags)) {
|
||||
|
||||
// Get the value of 'em'
|
||||
nsStyleFont font;
|
||||
mStyleContext->GetStyle(eStyleStruct_Font, font);
|
||||
float em = float(font.mFont.size);
|
||||
|
||||
// lspace = number h-unit
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
|
||||
nsMathMLAtoms::lspace_, value)) {
|
||||
nsCSSValue cssValue;
|
||||
if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) {
|
||||
mLeftSpace = float(CalcLength(aPresContext, mStyleContext, cssValue)) / em;
|
||||
}
|
||||
}
|
||||
else if (NS_MATHML_EMBELLISH_IS_ACCENT(mEmbellishData.flags)) {
|
||||
mLeftSpace = 0.0f;
|
||||
}
|
||||
|
||||
// rspace = number h-unit
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
|
||||
nsMathMLAtoms::rspace_, value)) {
|
||||
nsCSSValue cssValue;
|
||||
if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) {
|
||||
mRightSpace = float(CalcLength(aPresContext, mStyleContext, cssValue)) / em;
|
||||
}
|
||||
}
|
||||
else if (NS_MATHML_EMBELLISH_IS_ACCENT(mEmbellishData.flags)) {
|
||||
mRightSpace = 0.0f;
|
||||
}
|
||||
|
||||
// minsize = number [ v-unit | h-unit ]
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
|
||||
nsMathMLAtoms::minsize_, value)) {
|
||||
nsCSSValue cssValue;
|
||||
if (ParseNumericValue(value, cssValue)) {
|
||||
nsCSSUnit unit = cssValue.GetUnit();
|
||||
if (eCSSUnit_Number == unit)
|
||||
mMinSize = cssValue.GetFloatValue();
|
||||
else if (eCSSUnit_Percent == unit)
|
||||
mMinSize = cssValue.GetPercentValue();
|
||||
else if (eCSSUnit_Null != unit) {
|
||||
mMinSize = float(CalcLength(aPresContext, mStyleContext, cssValue));
|
||||
mFlags |= NS_MATHML_OPERATOR_MINSIZE_EXPLICIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// maxsize = number [ v-unit | h-unit ] | infinity
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
|
||||
nsMathMLAtoms::maxsize_, value)) {
|
||||
nsCSSValue cssValue;
|
||||
if (ParseNumericValue(value, cssValue)) {
|
||||
nsCSSUnit unit = cssValue.GetUnit();
|
||||
if (eCSSUnit_Number == unit)
|
||||
mMaxSize = cssValue.GetFloatValue();
|
||||
else if (eCSSUnit_Percent == unit)
|
||||
mMaxSize = cssValue.GetPercentValue();
|
||||
else if (eCSSUnit_Null != unit) {
|
||||
mMaxSize = float(CalcLength(aPresContext, mStyleContext, cssValue));
|
||||
mFlags |= NS_MATHML_OPERATOR_MAXSIZE_EXPLICIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the stretchy attribute has been disabled, the operator is not mutable
|
||||
if (!found || !NS_MATHML_OPERATOR_IS_STRETCHY(mFlags)) {
|
||||
mFlags &= ~NS_MATHML_OPERATOR_MUTABLE;
|
||||
|
@ -471,7 +528,7 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext,
|
|||
mEmbellishData.flags |= NS_MATHML_STRETCH_DONE;
|
||||
|
||||
// if (0 == mFlags) { // first time...
|
||||
InitData();
|
||||
InitData(aPresContext);
|
||||
// }
|
||||
|
||||
|
||||
|
@ -479,10 +536,12 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext,
|
|||
// See if it is okay to stretch
|
||||
|
||||
if (NS_MATHML_OPERATOR_IS_MUTABLE(mFlags)) {
|
||||
|
||||
nsStretchMetrics initialSize(aDesiredStretchSize);
|
||||
nsStretchMetrics container(aContainerSize);
|
||||
|
||||
// little adjustments if the operator is symmetric
|
||||
// XXX Also use maxsize and minsize to find what size we should
|
||||
// really suggest to our MathMLChar.
|
||||
|
||||
if (NS_MATHML_OPERATOR_IS_SYMMETRIC(mFlags) &&
|
||||
((aStretchDirection == NS_STRETCH_DIRECTION_VERTICAL) ||
|
||||
(aStretchDirection == NS_STRETCH_DIRECTION_DEFAULT &&
|
||||
|
@ -490,15 +549,72 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext,
|
|||
{
|
||||
container.ascent = PR_MAX(container.ascent, container.descent);
|
||||
container.descent = container.ascent;
|
||||
container.height = container.ascent + container.descent;
|
||||
container.height = container.ascent + container.descent;
|
||||
|
||||
// get ready in case we encounter user-desired min-max
|
||||
initialSize.ascent = PR_MAX(initialSize.ascent, initialSize.descent);
|
||||
initialSize.descent = initialSize.ascent;
|
||||
initialSize.height = initialSize.ascent + initialSize.descent;
|
||||
}
|
||||
|
||||
// check for user-desired min-max size
|
||||
|
||||
if (mMaxSize != float(NS_UNCONSTRAINEDSIZE) && mMaxSize > 0.0f) {
|
||||
// if we are here, there is a user defined maxsize ...
|
||||
if (NS_MATHML_OPERATOR_MAXSIZE_IS_EXPLICIT(mFlags)) {
|
||||
// there is an explicit value like maxsize="20pt"
|
||||
// try to maintain the aspect ratio of the char
|
||||
float aspect = mMaxSize / float(initialSize.ascent + initialSize.descent);
|
||||
container.ascent =
|
||||
PR_MIN(container.ascent, nscoord(initialSize.ascent * aspect));
|
||||
container.descent =
|
||||
PR_MIN(container.descent, nscoord(initialSize.descent * aspect));
|
||||
// below we use a type cast instead of a conversion to avoid a VC++ bug
|
||||
// see http://support.microsoft.com/support/kb/articles/Q115/7/05.ASP
|
||||
container.width =
|
||||
PR_MIN(container.width, (nscoord)mMaxSize);
|
||||
}
|
||||
else { // multiplicative value
|
||||
container.ascent =
|
||||
PR_MIN(container.ascent, nscoord(initialSize.ascent * mMaxSize));
|
||||
container.descent =
|
||||
PR_MIN(container.descent, nscoord(initialSize.descent * mMaxSize));
|
||||
container.width =
|
||||
PR_MIN(container.width, nscoord(initialSize.width * mMaxSize));
|
||||
}
|
||||
}
|
||||
|
||||
if (mMinSize != float(NS_UNCONSTRAINEDSIZE) && mMinSize > 0.0f) {
|
||||
// if we are here, there is a user defined minsize ...
|
||||
if (NS_MATHML_OPERATOR_MINSIZE_IS_EXPLICIT(mFlags)) {
|
||||
// there is an explicit value like minsize="20pt"
|
||||
// try to maintain the aspect ratio of the char
|
||||
float aspect = mMinSize / float(initialSize.ascent + initialSize.descent);
|
||||
container.ascent =
|
||||
PR_MAX(container.ascent, nscoord(initialSize.ascent * aspect));
|
||||
container.descent =
|
||||
PR_MAX(container.descent, nscoord(initialSize.descent * aspect));
|
||||
container.width =
|
||||
PR_MAX(container.width, (nscoord)mMinSize);
|
||||
}
|
||||
else { // multiplicative value
|
||||
container.ascent =
|
||||
PR_MAX(container.ascent, nscoord(initialSize.ascent * mMinSize));
|
||||
container.descent =
|
||||
PR_MAX(container.descent, nscoord(initialSize.descent * mMinSize));
|
||||
container.width =
|
||||
PR_MAX(container.width, nscoord(initialSize.width * mMinSize));
|
||||
}
|
||||
}
|
||||
|
||||
// things may have changed
|
||||
container.height = container.ascent + container.descent;
|
||||
|
||||
// let the MathMLChar stretch itself...
|
||||
nsStretchMetrics old(aDesiredStretchSize);
|
||||
mMathMLChar.Stretch(aPresContext, aRenderingContext,
|
||||
mStyleContext, aStretchDirection,
|
||||
container, aDesiredStretchSize);
|
||||
if (old == aDesiredStretchSize) { // hasn't changed !
|
||||
if (initialSize == aDesiredStretchSize) { // hasn't changed !
|
||||
mFlags &= ~NS_MATHML_OPERATOR_MUTABLE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,7 +74,8 @@ public:
|
|||
nsStretchMetrics& aDesiredStretchSize);
|
||||
|
||||
// helper method to lookup the operator dictionary and initialize our member data
|
||||
void InitData();
|
||||
void
|
||||
InitData(nsIPresContext* aPresContext);
|
||||
|
||||
protected:
|
||||
nsMathMLmoFrame();
|
||||
|
@ -82,10 +83,12 @@ protected:
|
|||
|
||||
virtual PRIntn GetSkipSides() const { return 0; }
|
||||
|
||||
nsMathMLChar mMathMLChar; // Here is the MathChar that will deal with the operator.
|
||||
nsMathMLChar mMathMLChar; // Here is the MathMLChar that will deal with the operator.
|
||||
nsOperatorFlags mFlags;
|
||||
float mLeftSpace;
|
||||
float mRightSpace;
|
||||
float mMinSize;
|
||||
float mMaxSize;
|
||||
};
|
||||
|
||||
#endif /* nsMathMLmoFrame_h___ */
|
||||
|
|
|
@ -77,19 +77,16 @@ nsMathMLmsubFrame::Init(nsIPresContext* aPresContext,
|
|||
nsresult rv = nsMathMLContainerFrame::Init
|
||||
(aPresContext, aContent, aParent, aContext, aPrevInFlow);
|
||||
|
||||
mSubScriptShiftFactor = 0.0;
|
||||
mSubScriptShift = 0;
|
||||
mScriptSpace = NSFloatPointsToTwips(0.5f); // 0.5pt as in plain TeX
|
||||
|
||||
// check for subscriptshift attribute in ex units
|
||||
// check if the subscriptshift attribute is there
|
||||
nsAutoString value;
|
||||
mUserSetFlag = PR_FALSE;
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute
|
||||
(kNameSpaceID_None, nsMathMLAtoms::subscriptshift_, value)) {
|
||||
PRInt32 aErrorCode;
|
||||
float aUserValue = value.ToFloat(&aErrorCode);
|
||||
if (NS_SUCCEEDED(aErrorCode)) {
|
||||
mUserSetFlag = PR_TRUE;
|
||||
mSubScriptShiftFactor = aUserValue;
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
|
||||
nsMathMLAtoms::subscriptshift_, value)) {
|
||||
nsCSSValue cssValue;
|
||||
if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) {
|
||||
mSubScriptShift = CalcLength(aPresContext, mStyleContext, cssValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,13 +170,9 @@ nsMathMLmsubFrame::Place(nsIPresContext* aPresContext,
|
|||
nscoord aSubScriptShift, dummy;
|
||||
// get aSubScriptShift default from font
|
||||
GetSubScriptShifts (fm, aSubScriptShift, dummy);
|
||||
if (mUserSetFlag) {
|
||||
// the user has set the subscriptshift attribute
|
||||
aSubScriptShift = NSToCoordRound(mSubScriptShiftFactor * xHeight);
|
||||
//XXX shouldn't this be
|
||||
// aSubScriptShift =
|
||||
// PR_MAX(aSubScriptShift, NSToCoordRound(mSubScriptShiftFactor * xHeight));
|
||||
}
|
||||
|
||||
aSubScriptShift =
|
||||
PR_MAX(aSubScriptShift, mSubScriptShift);
|
||||
|
||||
// get actual subscriptshift to be used
|
||||
// Rule 18b, App. G, TeXbook
|
||||
|
|
|
@ -72,8 +72,7 @@ public:
|
|||
private:
|
||||
nscoord mScriptSpace; // scriptspace from TeX for extra spacing after sup/subscript
|
||||
// = 0.5pt in plain TeX
|
||||
float mSubScriptShiftFactor;
|
||||
PRBool mUserSetFlag;
|
||||
nscoord mSubScriptShift;
|
||||
};
|
||||
|
||||
#endif /* nsMathMLmsubFrame_h___ */
|
||||
|
|
|
@ -77,29 +77,25 @@ nsMathMLmsubsupFrame::Init(nsIPresContext* aPresContext,
|
|||
nsresult rv = nsMathMLContainerFrame::Init
|
||||
(aPresContext, aContent, aParent, aContext, aPrevInFlow);
|
||||
|
||||
mSubScriptShiftFactor = 0.0f;
|
||||
mSupScriptShiftFactor = 0.0f;
|
||||
mSubScriptShift = 0;
|
||||
mSupScriptShift = 0;
|
||||
mScriptSpace = 0;
|
||||
|
||||
// check for subscriptshift and superscriptshift attribute in ex units
|
||||
// check if the subscriptshift attribute is there
|
||||
nsAutoString value;
|
||||
mSubUserSetFlag = mSupUserSetFlag = PR_FALSE;
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute
|
||||
(kNameSpaceID_None, nsMathMLAtoms::subscriptshift_, value)) {
|
||||
PRInt32 aErrorCode;
|
||||
float aUserValue = value.ToFloat(&aErrorCode);
|
||||
if (NS_SUCCEEDED(aErrorCode)) {
|
||||
mSubUserSetFlag = PR_TRUE;
|
||||
mSubScriptShiftFactor = aUserValue;
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
|
||||
nsMathMLAtoms::subscriptshift_, value)) {
|
||||
nsCSSValue cssValue;
|
||||
if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) {
|
||||
mSubScriptShift = CalcLength(aPresContext, mStyleContext, cssValue);
|
||||
}
|
||||
}
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute
|
||||
(kNameSpaceID_None, nsMathMLAtoms::superscriptshift_, value)) {
|
||||
PRInt32 aErrorCode;
|
||||
float aUserValue = value.ToFloat(&aErrorCode);
|
||||
if (NS_SUCCEEDED(aErrorCode)) {
|
||||
mSupUserSetFlag = PR_TRUE;
|
||||
mSupScriptShiftFactor = aUserValue;
|
||||
// check if the superscriptshift attribute is there
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
|
||||
nsMathMLAtoms::superscriptshift_, value)) {
|
||||
nsCSSValue cssValue;
|
||||
if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) {
|
||||
mSupScriptShift = CalcLength(aPresContext, mStyleContext, cssValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,10 +197,11 @@ nsMathMLmsubsupFrame::Place(nsIPresContext* aPresContext,
|
|||
|
||||
// Get aSubScriptShift{1,2} default from font
|
||||
GetSubScriptShifts (fm, aSubScriptShift1, aSubScriptShift2);
|
||||
if (mSubUserSetFlag) {
|
||||
|
||||
if (0 < mSubScriptShift) {
|
||||
// the user has set the subscriptshift attribute
|
||||
float aFactor = ((float) aSubScriptShift2) / aSubScriptShift1;
|
||||
aSubScriptShift1 = NSToCoordRound(mSubScriptShiftFactor * xHeight);
|
||||
aSubScriptShift1 = PR_MAX(aSubScriptShift1, mSubScriptShift);
|
||||
aSubScriptShift2 = NSToCoordRound(aFactor * aSubScriptShift1);
|
||||
}
|
||||
|
||||
|
@ -233,11 +230,11 @@ nsMathMLmsubsupFrame::Place(nsIPresContext* aPresContext,
|
|||
nscoord aSupScriptShift1, aSupScriptShift2, aSupScriptShift3;
|
||||
// Set aSupScriptShift{1,2,3} default from font
|
||||
GetSupScriptShifts (fm, aSupScriptShift1, aSupScriptShift2, aSupScriptShift3);
|
||||
if (mSupUserSetFlag) {
|
||||
if (0 < mSupScriptShift) {
|
||||
// the user has set the superscriptshift attribute
|
||||
float aFactor2 = ((float) aSupScriptShift2) / aSupScriptShift1;
|
||||
float aFactor3 = ((float) aSupScriptShift3) / aSupScriptShift1;
|
||||
aSupScriptShift1 = NSToCoordRound(mSupScriptShiftFactor * xHeight);
|
||||
aSupScriptShift1 = PR_MAX(aSupScriptShift1, mSupScriptShift);
|
||||
aSupScriptShift2 = NSToCoordRound(aFactor2 * aSupScriptShift1);
|
||||
aSupScriptShift3 = NSToCoordRound(aFactor3 * aSupScriptShift1);
|
||||
}
|
||||
|
@ -272,7 +269,7 @@ nsMathMLmsubsupFrame::Place(nsIPresContext* aPresContext,
|
|||
// Rule 18e, App. G, TeXbook
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
nscoord aRuleSize, dummy;
|
||||
nscoord aRuleSize;
|
||||
// XXX need to do update this ...
|
||||
GetRuleThickness (fm, aRuleSize);
|
||||
// aRuleSize /= 2;
|
||||
|
|
|
@ -72,8 +72,8 @@ protected:
|
|||
private:
|
||||
nscoord mScriptSpace; // scriptspace from TeX for extra spacing after sup/subscript
|
||||
// = 0.5pt in plain TeX
|
||||
float mSubScriptShiftFactor, mSupScriptShiftFactor;
|
||||
PRBool mSubUserSetFlag, mSupUserSetFlag;
|
||||
nscoord mSubScriptShift;
|
||||
nscoord mSupScriptShift;
|
||||
};
|
||||
|
||||
#endif /* nsMathMLmsubsupFrame_h___ */
|
||||
|
|
|
@ -76,19 +76,16 @@ nsMathMLmsupFrame::Init(nsIPresContext* aPresContext,
|
|||
nsresult rv = nsMathMLContainerFrame::Init
|
||||
(aPresContext, aContent, aParent, aContext, aPrevInFlow);
|
||||
|
||||
mSupScriptShiftFactor = 0.0f;
|
||||
mSupScriptShift = 0;
|
||||
mScriptSpace = NSFloatPointsToTwips(0.5f); // 0.5pt as in plain TeX
|
||||
|
||||
// check for superscriptshift attribute in ex units
|
||||
// check if the superscriptshift attribute is there
|
||||
nsAutoString value;
|
||||
mUserSetFlag = PR_FALSE;
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute
|
||||
(kNameSpaceID_None, nsMathMLAtoms::superscriptshift_, value)) {
|
||||
PRInt32 aErrorCode;
|
||||
float aUserValue = value.ToFloat(&aErrorCode);
|
||||
if (NS_SUCCEEDED(aErrorCode)) {
|
||||
mUserSetFlag = PR_TRUE;
|
||||
mSupScriptShiftFactor = aUserValue;
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
|
||||
nsMathMLAtoms::superscriptshift_, value)) {
|
||||
nsCSSValue cssValue;
|
||||
if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) {
|
||||
mSupScriptShift = CalcLength(aPresContext, mStyleContext, cssValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,14 +172,12 @@ nsMathMLmsupFrame::Place(nsIPresContext* aPresContext,
|
|||
// Set aSupScriptShift{1,2,3} default from font
|
||||
GetSupScriptShifts (fm, aSupScriptShift1, aSupScriptShift2, aSupScriptShift3);
|
||||
|
||||
if (mUserSetFlag) {
|
||||
// the user has set the supscriptshift attribute
|
||||
if (0 < mSupScriptShift) {
|
||||
// the user has set the superscriptshift attribute
|
||||
float aFactor2 = ((float) aSupScriptShift2) / aSupScriptShift1;
|
||||
float aFactor3 = ((float) aSupScriptShift3) / aSupScriptShift1;
|
||||
aSupScriptShift1 = NSToCoordRound(mSupScriptShiftFactor * xHeight);
|
||||
//XXX shouldn't this be
|
||||
// aSupScriptShift1 =
|
||||
// PR_MAX(aSupScriptShift1, NSToCoordRound(mSupScriptShiftFactor * xHeight));
|
||||
aSupScriptShift1 =
|
||||
PR_MAX(aSupScriptShift1, mSupScriptShift);
|
||||
aSupScriptShift2 = NSToCoordRound(aFactor2 * aSupScriptShift1);
|
||||
aSupScriptShift3 = NSToCoordRound(aFactor3 * aSupScriptShift1);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче