зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
b699957e56
Коммит
da41db0cc4
|
@ -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)) { // ×
|
||||
|
@ -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.
|
||||
/**************************************************************************/
|
||||
|
|
Загрузка…
Ссылка в новой задаче