bug 126619 - fixups for the final metrics of certain MathML characters, and add transliteration for U+2212 the official Unicode minus sign (ongoing bug 119664), r=roc+moz, rs=attinasi/blizzard, a=shaver

This commit is contained in:
rbs%maths.uq.edu.au 2002-02-27 01:35:27 +00:00
Родитель b699957e56
Коммит da41db0cc4
12 изменённых файлов: 237 добавлений и 118 удалений

Просмотреть файл

@ -87,6 +87,8 @@ entity.8289=
entity.8290=
# U+2146, DifferentialD, d for use in differentials, e.g., within integrals
entity.8518=d
# U+2212, MINUS SIGN, official Unicode minus sign
entity.8722=-
##
## End of hand coded section
## Below are generated from the unicode character database

Просмотреть файл

@ -110,6 +110,8 @@ entity.8289=
entity.8290=
# U+2146, DifferentialD, d for use in differentials, e.g., within integrals
entity.8518=d
# U+2212, MINUS SIGN, official Unicode minus sign
entity.8722=-
##
## End of hand coded section
## Below are generated from the unicode character database

Просмотреть файл

@ -437,6 +437,7 @@ operator.\u21A9.infix = stretchy:horizontal lspace:thickmathspace rspace:thickma
operator.\u21AA.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # ↪ ↪
operator.\u23B0.prefix = stretchy:vertical fence:true lspace:0em rspace:0em # ⎰ ⎰
operator.\u23B1.postfix = stretchy:vertical fence:true lspace:0em rspace:0em # ⎱ ⎱
operator.\u22C5.infix = lspace:thinmathspace rspace:thinmathspace # ċ
##################################################################################

Просмотреть файл

@ -918,7 +918,7 @@ nsGlyphTableList::GetPreferredListAt(nsIPresContext* aPresContext,
aGlyphTableList->Clear();
}
aGlyphTableList->AppendElement(glyphTable);
*aCount++;
++*aCount;
}
glyphTable = TableAt(++index);
}
@ -1851,36 +1851,38 @@ nsMathMLChar::Paint(nsIPresContext* aPresContext,
const nsStyleVisibility *visib = NS_STATIC_CAST(const nsStyleVisibility*,
styleContext->GetStyleData(eStyleStruct_Visibility));
if (visib->IsVisible() && NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer)
{
// if the leaf style context that we use for stretchy chars has a background
// color we use it -- this feature is mostly used for testing and debugging
// purposes. Normally, users will set the background on the container frame.
if (visib->IsVisible() && NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
if (mRect.width && mRect.height) {
// Paint our background and border
PRIntn skipSides = 0; //aForFrame->GetSkipSides();
const nsStyleBorder *border = NS_STATIC_CAST(const nsStyleBorder*,
styleContext->GetStyleData(eStyleStruct_Border));
const nsStyleOutline *outline = NS_STATIC_CAST(const nsStyleOutline*,
styleContext->GetStyleData(eStyleStruct_Outline));
// if the leaf style context that we use for stretchy chars has a background color
// we use it, otherwise we let the rendering code lookup in our parent context
const nsStyleBackground *backg = NS_STATIC_CAST(const nsStyleBackground*,
styleContext->GetStyleData(eStyleStruct_Background));
nsRect rect(mRect); //0, 0, mRect.width, mRect.height);
if (0 == (backg->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT))
if (styleContext != parentContext.get() &&
0 == (backg->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT))
nsCSSRendering::PaintBackgroundWithSC(aPresContext, aRenderingContext, aForFrame,
aDirtyRect, rect, *backg, *border, 0, 0);
else
nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, aForFrame,
aDirtyRect, rect, *border, 0, 0);
//else
// our container frame will take care of painting its background
// nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, aForFrame,
// aDirtyRect, rect, *border, 0, 0);
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
// for visual debug
PRIntn skipSides = 0; //aForFrame->GetSkipSides();
const nsStyleOutline *outline = NS_STATIC_CAST(const nsStyleOutline*,
styleContext->GetStyleData(eStyleStruct_Outline));
nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, aForFrame,
aDirtyRect, rect, *border, styleContext, skipSides);
nsCSSRendering::PaintOutline(aPresContext, aRenderingContext, aForFrame,
aDirtyRect, rect, *border, *outline, styleContext, 0);
#endif
}
}
if (visib->IsVisible() && NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer)
{
if (visib->IsVisible() && NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
// Set color ...
const nsStyleColor *color = NS_STATIC_CAST(const nsStyleColor*,
styleContext->GetStyleData(eStyleStruct_Color));
@ -2072,7 +2074,7 @@ nsMathMLChar::PaintVertically(nsIPresContext* aPresContext,
rbearing = bmdata[first].rightBearing;
}
else {
NS_ASSERTION(PR_FALSE, "Cannot stretch - All parts missing");
NS_ERROR("Cannot stretch - All parts missing");
return NS_ERROR_UNEXPECTED;
}
// paint the rule between the parts
@ -2108,7 +2110,7 @@ nsMathMLChar::PaintVertically(nsIPresContext* aPresContext,
count++;
dy += stride;
aGlyphTable->DrawGlyph(aRenderingContext, aFont, glue, dx, dy);
// NS_ASSERTION(5000 == count, "Error - glyph table is incorrectly set");
NS_ASSERTION(1000 != count, "something is probably wrong somewhere");
if (1000 == count) return NS_ERROR_UNEXPECTED;
}
aRenderingContext.PopState(clipState);
@ -2250,7 +2252,7 @@ nsMathMLChar::PaintHorizontally(nsIPresContext* aPresContext,
descent = bmdata[first].descent;
}
else {
NS_ASSERTION(PR_FALSE, "Cannot stretch - All parts missing");
NS_ERROR("Cannot stretch - All parts missing");
return NS_ERROR_UNEXPECTED;
}
// paint the rule between the parts
@ -2286,7 +2288,7 @@ nsMathMLChar::PaintHorizontally(nsIPresContext* aPresContext,
count++;
dx += stride;
aGlyphTable->DrawGlyph(aRenderingContext, aFont, glue, dx, dy);
// NS_ASSERTION(5000 == count, "Error - glyph table is incorrectly set");
NS_ASSERTION(1000 != count, "something is probably wrong somewhere");
if (1000 == count) return NS_ERROR_UNEXPECTED;
}
aRenderingContext.PopState(clipState);

Просмотреть файл

@ -1463,7 +1463,13 @@ nsMathMLContainerFrame::Place(nsIPresContext* aPresContext,
aDesiredSize.descent = childSize.descent;
mBoundingMetrics = bmChild;
// update to include the left correction
mBoundingMetrics.leftBearing += leftCorrection;
// but leave <msqrt> alone because the sqrt glyph itself is there first
nsCOMPtr<nsIAtom> tag;
mContent->GetTag(*getter_AddRefs(tag));
if (tag.get() == nsMathMLAtoms::msqrt_)
leftCorrection = 0;
else
mBoundingMetrics.leftBearing += leftCorrection;
}
else {
if (aDesiredSize.descent < childSize.descent)
@ -1510,8 +1516,16 @@ nsMathMLContainerFrame::Place(nsIPresContext* aPresContext,
nsCOMPtr<nsIAtom> childFrameType;
childFrame->GetFrameType(getter_AddRefs(childFrameType));
GetReflowAndBoundingMetricsFor(childFrame, childSize, bmChild);
GetItalicCorrection(bmChild, leftCorrection, italicCorrection);
dy = aDesiredSize.ascent - childSize.ascent;
if (0 < count) {
if (0 == count) {
// for <msqrt>, the sqrt glyph itself is there first
nsCOMPtr<nsIAtom> tag;
mContent->GetTag(*getter_AddRefs(tag));
if (tag.get() == nsMathMLAtoms::msqrt_)
leftCorrection = 0;
}
else {
// add inter frame spacing
nscoord space = GetInterFrameSpacing(mPresentationData.scriptLevel,
prevFrameType, childFrameType);
@ -1519,7 +1533,6 @@ nsMathMLContainerFrame::Place(nsIPresContext* aPresContext,
}
count++;
prevFrameType = childFrameType;
GetItalicCorrection(bmChild, leftCorrection, italicCorrection);
// add left correction
dx += leftCorrection;
FinishReflowChild(childFrame, aPresContext, nsnull, childSize, dx, dy, 0);

Просмотреть файл

@ -369,10 +369,22 @@ public:
// re-resolve our subtree to set any mathml-expected data
nsMathMLContainerFrame::MapAttributesIntoCSS(aPresContext, this);
nsMathMLContainerFrame::RebuildAutomaticDataForChildren(aPresContext, this);
nsMathMLContainerFrame::PropagateScriptStyleFor(aPresContext, this, 0);
return rv;
}
NS_IMETHOD
Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
if (mScriptStyleChanged) {
mScriptStyleChanged = PR_FALSE;
nsMathMLContainerFrame::PropagateScriptStyleFor(aPresContext, this, 0);
}
return nsBlockFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
}
NS_IMETHOD
AppendFrames(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
@ -422,6 +434,15 @@ public:
protected:
nsMathMLmathBlockFrame() {}
virtual ~nsMathMLmathBlockFrame() {}
NS_IMETHOD
DidSetStyleContext(nsIPresContext* aPresContext)
{
mScriptStyleChanged = PR_TRUE;
return nsBlockFrame::DidSetStyleContext(aPresContext);
}
PRBool mScriptStyleChanged;
};
// --------------
@ -439,10 +460,22 @@ public:
// re-resolve our subtree to set any mathml-expected data
nsMathMLContainerFrame::MapAttributesIntoCSS(aPresContext, this);
nsMathMLContainerFrame::RebuildAutomaticDataForChildren(aPresContext, this);
nsMathMLContainerFrame::PropagateScriptStyleFor(aPresContext, this, 0);
return rv;
}
NS_IMETHOD
Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
if (mScriptStyleChanged) {
mScriptStyleChanged = PR_FALSE;
nsMathMLContainerFrame::PropagateScriptStyleFor(aPresContext, this, 0);
}
return nsInlineFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
}
NS_IMETHOD
AppendFrames(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
@ -492,6 +525,15 @@ public:
protected:
nsMathMLmathInlineFrame() {}
virtual ~nsMathMLmathInlineFrame() {}
NS_IMETHOD
DidSetStyleContext(nsIPresContext* aPresContext)
{
mScriptStyleChanged = PR_TRUE;
return nsInlineFrame::DidSetStyleContext(aPresContext);
}
PRBool mScriptStyleChanged;
};
#endif /* nsMathMLContainerFrame_h___ */

Просмотреть файл

@ -304,7 +304,7 @@ nsMathMLFrame::GetAxisHeight(nsIRenderingContext& aRenderingContext,
#endif
nscoord xHeight;
aFontMetrics->GetXHeight(xHeight);
PRUnichar minus = '-';
PRUnichar minus = 0x2212; // not '-', but official Unicode minus sign
nsBoundingMetrics bm;
nsresult rv = aRenderingContext.GetBoundingMetrics(&minus, PRUint32(1), bm);
if (NS_SUCCEEDED(rv)) {
@ -314,18 +314,6 @@ nsMathMLFrame::GetAxisHeight(nsIRenderingContext& aRenderingContext,
// fall-back to the other version
GetAxisHeight(aFontMetrics, aAxisHeight);
}
#if 0
nscoord oldAxis;
GetAxisHeight(aFontMetrics, oldAxis);
PRUnichar plus = '+';
rv = aRenderingContext.GetBoundingMetrics(&plus, PRUint32(1), bm);
nscoord plusAxis = bm.ascent - (bm.ascent + bm.descent)/2;;
printf("xheight:%4d Axis:%4d oldAxis:%4d plusAxis:%4d\n",
xHeight, aAxisHeight, oldAxis, plusAxis);
#endif
}
// ================
@ -536,23 +524,26 @@ nsCSSMapping {
};
static void
GetMathMLAttributeStyleSheet(nsIDocument* aDocument,
GetMathMLAttributeStyleSheet(nsIPresContext* aPresContext,
nsIStyleSheet** aSheet)
{
static const char kTitle[] = "Internal MathML/CSS Attribute Style Sheet";
*aSheet = nsnull;
// first, look if the attribute stylesheet is already there
nsCOMPtr<nsIPresShell> presShell;
aPresContext->GetShell(getter_AddRefs(presShell));
nsCOMPtr<nsIStyleSet> styleSet;
presShell->GetStyleSet(getter_AddRefs(styleSet));
if (!styleSet)
return;
nsAutoString title;
PRInt32 count;
aDocument->GetNumberOfStyleSheets(&count);
for (PRInt32 i = 0; i < count; ++i) {
nsCOMPtr<nsIStyleSheet> sheet;
aDocument->GetStyleSheetAt(i, getter_AddRefs(sheet));
for (PRInt32 i = styleSet->GetNumberOfAgentStyleSheets() - 1; i >= 0; --i) {
nsCOMPtr<nsIStyleSheet> sheet = getter_AddRefs(styleSet->GetAgentStyleSheetAt(i));
nsCOMPtr<nsICSSStyleSheet> cssSheet(do_QueryInterface(sheet));
if (cssSheet) {
cssSheet->GetTitle(title);
if (title.EqualsIgnoreCase(kTitle)) {
if (title.Equals(NS_ConvertASCIItoUCS2(kTitle))) {
*aSheet = sheet;
NS_IF_ADDREF(*aSheet);
return;
@ -573,11 +564,8 @@ GetMathMLAttributeStyleSheet(nsIDocument* aDocument,
cssSheet->SetDefaultNameSpaceID(nsMathMLAtoms::nameSpaceID);
nsCOMPtr<nsIStyleSheet> sheet(do_QueryInterface(cssSheet));
// insert the stylesheet into the document without notifying observers
// (discovered that it will actually be inserted at position 1 since style
// sheets are internally arrayed between a nsIHTMLStyleSheet attribute sheet
// at the beginning and a nsIHTMLCSSStyleSheet inline sheet at the end...)
aDocument->InsertStyleSheetAt(sheet, 0, PR_FALSE);
// insert the stylesheet into the styleset without notifying observers
styleSet->AppendAgentStyleSheet(sheet);
*aSheet = sheet;
NS_ADDREF(*aSheet);
}
@ -659,7 +647,7 @@ nsMathMLFrame::MapAttributesIntoCSS(nsIPresContext* aPresContext,
aContent->GetDocument(*getter_AddRefs(doc));
if (!doc)
return 0;
GetMathMLAttributeStyleSheet(doc, getter_AddRefs(sheet));
GetMathMLAttributeStyleSheet(aPresContext, getter_AddRefs(sheet));
if (!sheet)
return 0;
// by construction, these cannot be null at this point

Просмотреть файл

@ -268,7 +268,19 @@ nsMathMLmfencedFrame::doReflow(nsIPresContext* aPresContext,
nsMathMLContainerFrame* mathMLFrame =
NS_STATIC_CAST(nsMathMLContainerFrame*, aForFrame);
PRInt32 i;
const nsStyleFont* font;
aForFrame->GetStyleData(eStyleStruct_Font, (const nsStyleStruct *&)font);
nsCOMPtr<nsIFontMetrics> fm;
aReflowState.rendContext->SetFont(font->mFont);
aReflowState.rendContext->GetFontMetrics(*getter_AddRefs(fm));
nscoord axisHeight, em;
GetAxisHeight(*aReflowState.rendContext, fm, axisHeight);
GetEmHeight(fm, em);
// leading to be left at the top and the bottom of stretched chars
nscoord leading = NSToCoordRound(0.2f * em);
/////////////
// Reflow children
// Asking each child to cache its bounding metrics
@ -287,6 +299,12 @@ nsMathMLmfencedFrame::doReflow(nsIPresContext* aPresContext,
nsIFrame* firstChild;
aForFrame->FirstChild(aPresContext, nsnull, &firstChild);
nsIFrame* childFrame = firstChild;
if (firstChild || aOpenChar || aCloseChar || aSeparatorsCount > 0) {
// We use the ASCII metrics to get our minimum height. This way, if we have
// borders or a background, they will fit better with other elements on the line
fm->GetMaxAscent(aDesiredSize.ascent);
fm->GetMaxDescent(aDesiredSize.descent);
}
while (childFrame) {
nsHTMLReflowState childReflowState(aPresContext, aReflowState,
childFrame, availSize);
@ -360,16 +378,6 @@ nsMathMLmfencedFrame::doReflow(nsIPresContext* aPresContext,
// Prepare the opening fence, separators, and closing fence, and
// adjust the origin of children.
PRInt32 i;
const nsStyleFont* font;
aForFrame->GetStyleData(eStyleStruct_Font, (const nsStyleStruct *&)font);
nsCOMPtr<nsIFontMetrics> fm;
aReflowState.rendContext->SetFont(font->mFont);
aReflowState.rendContext->GetFontMetrics(*getter_AddRefs(fm));
nscoord axisHeight, em;
GetAxisHeight(*aReflowState.rendContext, fm, axisHeight);
GetEmHeight(fm, em);
// we need to center around the axis
if (firstChild) { // do nothing for an empty <mfenced></mfenced>
nscoord delta = PR_MAX(containerSize.ascent - axisHeight,
@ -382,19 +390,19 @@ nsMathMLmfencedFrame::doReflow(nsIPresContext* aPresContext,
// opening fence ...
ReflowChar(aPresContext, *aReflowState.rendContext, aOpenChar,
NS_MATHML_OPERATOR_FORM_PREFIX, presentationData.scriptLevel,
axisHeight, em, containerSize, aDesiredSize);
axisHeight, leading, em, containerSize, aDesiredSize);
/////////////////
// separators ...
for (i = 0; i < aSeparatorsCount; i++) {
ReflowChar(aPresContext, *aReflowState.rendContext, &aSeparatorsChar[i],
NS_MATHML_OPERATOR_FORM_INFIX, presentationData.scriptLevel,
axisHeight, em, containerSize, aDesiredSize);
axisHeight, leading, em, containerSize, aDesiredSize);
}
/////////////////
// closing fence ...
ReflowChar(aPresContext, *aReflowState.rendContext, aCloseChar,
NS_MATHML_OPERATOR_FORM_POSTFIX, presentationData.scriptLevel,
axisHeight, em, containerSize, aDesiredSize);
axisHeight, leading, em, containerSize, aDesiredSize);
//////////////////
// Adjust the origins of each child.
@ -465,6 +473,7 @@ nsMathMLmfencedFrame::ReflowChar(nsIPresContext* aPresContext,
nsOperatorFlags aForm,
PRInt32 aScriptLevel,
nscoord axisHeight,
nscoord leading,
nscoord em,
nsBoundingMetrics& aContainerSize,
nsHTMLReflowMetrics& aDesiredSize)
@ -473,7 +482,7 @@ nsMathMLmfencedFrame::ReflowChar(nsIPresContext* aPresContext,
nsOperatorFlags flags = 0;
float leftSpace = 0.0f;
float rightSpace = 0.0f;
nsAutoString data;
aMathMLChar->GetData(data);
PRBool found = nsMathMLOperators::LookupOperator(data, aForm,
@ -491,8 +500,7 @@ nsMathMLmfencedFrame::ReflowChar(nsIPresContext* aPresContext,
NS_STRETCH_DIRECTION_VERTICAL,
aContainerSize, charSize);
if (NS_STRETCH_DIRECTION_UNSUPPORTED != aMathMLChar->GetStretchDirection())
{
if (NS_STRETCH_DIRECTION_UNSUPPORTED != aMathMLChar->GetStretchDirection()) {
// has changed... so center the char around the axis
nscoord height = charSize.ascent + charSize.descent;
charSize.ascent = height/2 + axisHeight;
@ -501,6 +509,7 @@ nsMathMLmfencedFrame::ReflowChar(nsIPresContext* aPresContext,
else {
// either it hasn't changed or stretching the char failed (i.e.,
// GetBoundingMetrics failed)
leading = 0;
if (NS_FAILED(res)) {
nsTextDimensions dimensions;
aRenderingContext.GetTextDimensions(data.get(), data.Length(), dimensions);
@ -513,10 +522,10 @@ nsMathMLmfencedFrame::ReflowChar(nsIPresContext* aPresContext,
}
}
if (aDesiredSize.ascent < charSize.ascent)
aDesiredSize.ascent = charSize.ascent;
if (aDesiredSize.descent < charSize.descent)
aDesiredSize.descent = charSize.descent;
if (aDesiredSize.ascent < charSize.ascent + leading)
aDesiredSize.ascent = charSize.ascent + leading;
if (aDesiredSize.descent < charSize.descent + leading)
aDesiredSize.descent = charSize.descent + leading;
// account the spacing
charSize.width += NSToCoordRound((leftSpace + rightSpace) * em);
@ -542,22 +551,20 @@ nsMathMLmfencedFrame::PlaceChar(nsMathMLChar* aMathMLChar,
// the char's y-origin was used to store the ascent ...
nsRect rect;
aMathMLChar->GetRect(rect);
nscoord dy = aDesiredAscent - rect.y;
if (aMathMLChar->GetStretchDirection() != NS_STRETCH_DIRECTION_UNSUPPORTED)
{
if (aMathMLChar->GetStretchDirection() != NS_STRETCH_DIRECTION_UNSUPPORTED) {
// the stretchy char will be centered around the axis
// so we adjust the returned bounding metrics accordingly
bm.descent = (bm.ascent + bm.descent) - rect.y;
bm.ascent = rect.y;
}
aMathMLChar->SetRect(nsRect(dx + rect.x, dy,
bm.width, rect.height));
aMathMLChar->SetRect(nsRect(dx + rect.x, dy, bm.width, rect.height));
bm.leftBearing += rect.x;
bm.rightBearing += rect.x;
// return rect.width since it includes lspace and rspace
bm.width = rect.width;
dx += rect.width;

Просмотреть файл

@ -92,6 +92,7 @@ public:
nsOperatorFlags aForm,
PRInt32 aScriptLevel,
nscoord axisHeight,
nscoord leading,
nscoord em,
nsBoundingMetrics& aContainerSize,
nsHTMLReflowMetrics& aDesiredSize);

Просмотреть файл

@ -80,8 +80,15 @@ nsMathMLmoFrame::Paint(nsIPresContext* aPresContext,
PRUint32 aFlags)
{
nsresult rv = NS_OK;
if (NS_MATHML_OPERATOR_GET_FORM(mFlags) ||
NS_MATHML_OPERATOR_IS_CENTERED(mFlags)) {
PRBool useMathMLChar =
NS_MATHML_OPERATOR_GET_FORM(mFlags) ||
NS_MATHML_OPERATOR_IS_CENTERED(mFlags);
if (!useMathMLChar || NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
// let the base class paint the background, border, outline
rv = nsMathMLContainerFrame::Paint(aPresContext, aRenderingContext,
aDirtyRect, aWhichLayer);
}
if (useMathMLChar) {
rv = mMathMLChar.Paint(aPresContext, aRenderingContext,
aDirtyRect, aWhichLayer, this);
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
@ -97,10 +104,6 @@ nsMathMLmoFrame::Paint(nsIPresContext* aPresContext,
}
#endif
}
else { // let the base class worry about the painting
rv = nsMathMLContainerFrame::Paint(aPresContext, aRenderingContext,
aDirtyRect, aWhichLayer);
}
return rv;
}
@ -127,6 +130,15 @@ nsMathMLmoFrame::ProcessTextData(nsIPresContext* aPresContext)
}
}
}
PRInt32 length = data.Length();
// special... in math mode, the usual minus sign '-' looks too short, so
// what we do here is to remap <mo>-</mo> to the official Unicode minus
// sign (U+2212) which looks much better. For background on this, see
// http://groups.google.com/groups?hl=en&th=66488daf1ade7635&rnum=1
if (1 == length && data[0] == '-') {
data = PRUnichar(0x2212);
}
// cache the special bits: mutable, accent, movablelimits, centered.
// we need to do this in anticipation of other requirements, and these
@ -153,7 +165,7 @@ nsMathMLmoFrame::ProcessTextData(nsIPresContext* aPresContext)
// see if this is an operator that should be centered to cater for
// fonts that are not math-aware
if (1 == data.Length()) {
if (1 == length) {
PRUnichar ch = data[0];
if ((ch == '+') || (ch == '=') || (ch == '*') ||
(ch == 0x00D7)) { // &times;
@ -167,9 +179,10 @@ nsMathMLmoFrame::ProcessTextData(nsIPresContext* aPresContext)
}
// get our 'form' and lookup in the Operator Dictionary to fetch
// our default data that may come from there, the look our attributes.
// The function has to be called during reflow because certain value
// before, we will re-use unchanged things that we computed earlier
// our default data that may come from there. Then complete our setup
// using attributes that we may have. To stay in sync, this function is
// called very often. We depend on many things that may change around us.
// However, we re-use unchanged values.
void
nsMathMLmoFrame::ProcessOperatorData(nsIPresContext* aPresContext)
{
@ -302,7 +315,7 @@ nsMathMLmoFrame::ProcessOperatorData(nsIPresContext* aPresContext)
nsAutoString data;
mMathMLChar.GetData(data);
PRBool found = nsMathMLOperators::LookupOperator(data, form, &mFlags, &lspace, &rspace);
if (found) {
if (found && (lspace || rspace)) {
// cache the default values of lspace & rspace that we get from the dictionary.
// since these values are relative to the 'em' unit, convert to twips now
nscoord em;
@ -349,7 +362,8 @@ nsMathMLmoFrame::ProcessOperatorData(nsIPresContext* aPresContext)
leftSpace = CalcLength(aPresContext, mStyleContext, cssValue);
}
}
else if (NS_MATHML_EMBELLISH_IS_ACCENT(mEmbellishData.flags)) {
else if (mPresentationData.scriptLevel > 0 &&
NS_MATHML_EMBELLISH_IS_ACCENT(mEmbellishData.flags)) {
leftSpace = 0;
}
@ -367,15 +381,28 @@ nsMathMLmoFrame::ProcessOperatorData(nsIPresContext* aPresContext)
rightSpace = CalcLength(aPresContext, mStyleContext, cssValue);
}
}
else if (NS_MATHML_EMBELLISH_IS_ACCENT(mEmbellishData.flags)) {
else if (mPresentationData.scriptLevel > 0 &&
NS_MATHML_EMBELLISH_IS_ACCENT(mEmbellishData.flags)) {
rightSpace = 0;
}
// little extra tuning to round lspace & rspace to at least a pixel so that
// operators don't look as if they are colliding with their operands
if (leftSpace || rightSpace) {
float p2t;
aPresContext->GetScaledPixelsToTwips(&p2t);
nscoord onePixel = NSIntPixelsToTwips(1, p2t);
if (leftSpace && leftSpace < onePixel)
leftSpace = onePixel;
if (rightSpace && rightSpace < onePixel)
rightSpace = onePixel;
}
// the values that we get from our attributes override the dictionary
mEmbellishData.leftSpace = leftSpace;
mEmbellishData.rightSpace = rightSpace;
// Nows see if there are user-defined attributes that override the dictionary.
// 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...
@ -505,15 +532,17 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext,
nsCOMPtr<nsIFontMetrics> fm;
aRenderingContext.SetFont(font->mFont);
aRenderingContext.GetFontMetrics(*getter_AddRefs(fm));
nscoord leading, axisHeight, height;
nscoord leading = 0, axisHeight, height;
GetAxisHeight(aRenderingContext, fm, axisHeight);
// Operators that exist in the dictionary, or those that are to be centered
// to cater for fonts that are not math-aware, are handled by the MathMLChar
PRBool useMathMLChar =
NS_MATHML_OPERATOR_GET_FORM(mFlags) ||
NS_MATHML_OPERATOR_IS_CENTERED(mFlags);;
if (NS_MATHML_OPERATOR_GET_FORM(mFlags) ||
NS_MATHML_OPERATOR_IS_CENTERED(mFlags)) {
nsBoundingMetrics charSize;
nsBoundingMetrics charSize;
if (useMathMLChar) {
nsBoundingMetrics initialSize = aDesiredStretchSize.mBoundingMetrics;
nsBoundingMetrics container = initialSize;
@ -644,15 +673,16 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext,
// gracefully handle cases where stretching the char failed (i.e., GetBoundingMetrics failed)
// clear our 'form' to behave as if the operator wasn't in the dictionary
mFlags &= ~NS_MATHML_OPERATOR_FORM;
useMathMLChar = PR_FALSE;
}
else {
// update our bounding metrics... it becomes that of our MathML char
mMathMLChar.GetBoundingMetrics(mBoundingMetrics);
mBoundingMetrics = charSize;
// if the returned direction is 'unsupported', the char didn't actually change.
// So we do the centering only if necessary
if ((mMathMLChar.GetStretchDirection() != NS_STRETCH_DIRECTION_UNSUPPORTED)
|| NS_MATHML_OPERATOR_IS_CENTERED(mFlags)) {
if (mMathMLChar.GetStretchDirection() != NS_STRETCH_DIRECTION_UNSUPPORTED ||
NS_MATHML_OPERATOR_IS_CENTERED(mFlags)) {
if (isVertical || NS_MATHML_OPERATOR_IS_CENTERED(mFlags)) {
// the desired size returned by mMathMLChar maybe different
@ -677,30 +707,44 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext,
// this seems more reliable than using fm->GetLeading() on suspicious fonts
nscoord em;
GetEmHeight(fm, em);
leading = NSToCoordRound(0.2f * em);
aDesiredStretchSize.ascent = mBoundingMetrics.ascent + leading;
aDesiredStretchSize.descent = mBoundingMetrics.descent + leading;
leading = NSToCoordRound(0.2f * em); // so, leading remains 0 if we don't get here
}
aDesiredStretchSize.height = aDesiredStretchSize.ascent + aDesiredStretchSize.descent;
aDesiredStretchSize.width = mBoundingMetrics.width;
aDesiredStretchSize.mBoundingMetrics = mBoundingMetrics;
nscoord dy = aDesiredStretchSize.ascent - mBoundingMetrics.ascent;
mMathMLChar.SetRect(
nsRect(0, dy, charSize.width, charSize.ascent + charSize.descent));
mReference.x = 0;
mReference.y = aDesiredStretchSize.ascent;
}
}
if (!NS_MATHML_OPERATOR_GET_FORM(mFlags) &&
!NS_MATHML_OPERATOR_IS_CENTERED(mFlags)) {
if (!useMathMLChar) {
// Place our children using the default method
Place(aPresContext, aRenderingContext, PR_TRUE, aDesiredStretchSize);
}
// Fixup for the final height.
// On one hand, our stretchy height can sometimes be shorter than surrounding
// ASCII chars, e.g., arrow symbols have |mBoundingMetrics.ascent + leading|
// that is smaller than the ASCII's ascent, hence when painting the background
// later, it won't look uniform along the line.
// On the other hand, sometimes we may leave too much gap when our glyph happens
// to come from a font with tall glyphs. For example, since CMEX10 has very tall
// glyphs, its natural font metrics are large, even if we pick a small glyph
// whose size is comparable to the size of a normal ASCII glyph.
// So to avoid uneven spacing in either of these two cases, we use the height
// of the ASCII font as a reference and try to match it if possible.
nscoord ascent, descent;
fm->GetMaxAscent(ascent);
fm->GetMaxDescent(descent);
aDesiredStretchSize.ascent = PR_MAX(mBoundingMetrics.ascent + leading, ascent);
aDesiredStretchSize.descent = PR_MAX(mBoundingMetrics.descent + leading, descent);
aDesiredStretchSize.height = aDesiredStretchSize.ascent + aDesiredStretchSize.descent;
aDesiredStretchSize.width = mBoundingMetrics.width;
aDesiredStretchSize.mBoundingMetrics = mBoundingMetrics;
mReference.x = 0;
mReference.y = aDesiredStretchSize.ascent;
// Place our mMathMLChar, its origin is in our coordinate system
if (useMathMLChar) {
nscoord dy = aDesiredStretchSize.ascent - mBoundingMetrics.ascent;
mMathMLChar.GetBoundingMetrics(charSize);
mMathMLChar.SetRect(nsRect(0, dy, charSize.width, charSize.ascent + charSize.descent));
}
// Before we leave... there is a last item in the check-list:
// If our parent is not embellished, it means we are the outermost embellished
// container and so we put the spacing, otherwise we don't include the spacing,
@ -723,7 +767,7 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext,
aDesiredStretchSize.mBoundingMetrics.rightBearing += dx;
nsRect rect;
if (NS_MATHML_OPERATOR_GET_FORM(mFlags)) {
if (useMathMLChar) {
mMathMLChar.GetRect(rect);
mMathMLChar.SetRect(nsRect(rect.x + dx, rect.y, rect.width, rect.height));
}

Просмотреть файл

@ -92,6 +92,17 @@ public:
NS_IMETHOD
TransmitAutomaticData(nsIPresContext* aPresContext);
virtual nsresult
FixInterFrameSpacing(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize)
{
// XXX the base method doesn't work properly with <msqrt> because it
// only slides child frames and has no idea that we have a sqrt glyph
// that is part of the flow without being a frame. We need to shift our
// sqrt glyph too, but since m0.9.9 is going out... do nothing for now
return NS_OK;
}
protected:
nsMathMLmsqrtFrame();
virtual ~nsMathMLmsqrtFrame();

Просмотреть файл

@ -378,18 +378,24 @@ mtd[-moz-math-columnline="dashed"] {
Authors can make elements on a document to be stretched with different
fonts, e.g.,
To request the use of TeX fonts, you can do:
To request the use of TeX fonts, you can add a <style>...</style> with:
<mo myfonts="tex">...</mo> with the associated CSS declaration
mo[myfonts="tex"]:-moz-math-font-style-stretchy {
font-family: CMSY10, CMEX10;
}
To request the use of Mathematica fonts, you can do:
To request the use of Mathematica fonts, you can add a <style>...</style> with:
<mo myfonts="mathematica">...</mo> with the associated CSS declaration
mo[myfonts="mathematica"]:-moz-math-font-style-stretchy {
font-family: Math1, Math2, Math4;
}
Of course, if you just want all of the stretchy characters in your
document to be stretched with your preferred list, you can just do:
:-moz-math-font-style-stretchy {
font-family: [your-particular-list]
}
Note that like other fonts in the document, users can override this by
clicking the pref to override document fonts.
/**************************************************************************/