зеркало из https://github.com/mozilla/gecko-dev.git
Bug 875294 - Implement menclose notation "updiagonalarrow". r=karlt
This commit is contained in:
Родитель
f9d3e576ba
Коммит
96a807cb7d
|
@ -29,6 +29,9 @@ static const PRUnichar kLongDivChar = ')';
|
|||
// radical: 'SQUARE ROOT'
|
||||
static const PRUnichar kRadicalChar = 0x221A;
|
||||
|
||||
// updiagonalstrike
|
||||
static const uint8_t kArrowHeadSize = 10;
|
||||
|
||||
nsIFrame*
|
||||
NS_NewMathMLmencloseFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
|
||||
{
|
||||
|
@ -115,6 +118,8 @@ nsresult nsMathMLmencloseFrame::AddNotation(const nsAString& aNotation)
|
|||
mNotationsToDraw |= NOTATION_BOTTOM;
|
||||
} else if (aNotation.EqualsLiteral("updiagonalstrike")) {
|
||||
mNotationsToDraw |= NOTATION_UPDIAGONALSTRIKE;
|
||||
} else if (aNotation.EqualsLiteral("updiagonalarrow")) {
|
||||
mNotationsToDraw |= NOTATION_UPDIAGONALARROW;
|
||||
} else if (aNotation.EqualsLiteral("downdiagonalstrike")) {
|
||||
mNotationsToDraw |= NOTATION_DOWNDIAGONALSTRIKE;
|
||||
} else if (aNotation.EqualsLiteral("verticalstrike")) {
|
||||
|
@ -146,6 +151,14 @@ void nsMathMLmencloseFrame::InitNotations()
|
|||
|
||||
while (tokenizer.hasMoreTokens())
|
||||
AddNotation(tokenizer.nextToken());
|
||||
|
||||
if (IsToDraw(NOTATION_UPDIAGONALARROW)) {
|
||||
// For <menclose notation="updiagonalstrike updiagonalarrow">, if
|
||||
// the two notations are drawn then the strike line may cause the point of
|
||||
// the arrow to be too wide. Hence we will only draw the updiagonalarrow
|
||||
// and the arrow shaft may be thought to be the updiagonalstrike.
|
||||
mNotationsToDraw &= ~NOTATION_UPDIAGONALSTRIKE;
|
||||
}
|
||||
} else {
|
||||
// default: longdiv
|
||||
if (NS_FAILED(AllocateMathMLChar(NOTATION_LONGDIV)))
|
||||
|
@ -251,6 +264,11 @@ nsMathMLmencloseFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
mRuleThickness, NOTATION_UPDIAGONALSTRIKE);
|
||||
}
|
||||
|
||||
if (IsToDraw(NOTATION_UPDIAGONALARROW)) {
|
||||
DisplayNotation(aBuilder, this, mencloseRect, aLists,
|
||||
mRuleThickness, NOTATION_UPDIAGONALARROW);
|
||||
}
|
||||
|
||||
if (IsToDraw(NOTATION_DOWNDIAGONALSTRIKE)) {
|
||||
DisplayNotation(aBuilder, this, mencloseRect, aLists,
|
||||
mRuleThickness, NOTATION_DOWNDIAGONALSTRIKE);
|
||||
|
@ -370,6 +388,7 @@ nsMathMLmencloseFrame::PlaceInternal(nsRenderingContext& aRenderingContext,
|
|||
if (IsToDraw(NOTATION_RIGHT) ||
|
||||
IsToDraw(NOTATION_LEFT) ||
|
||||
IsToDraw(NOTATION_UPDIAGONALSTRIKE) ||
|
||||
IsToDraw(NOTATION_UPDIAGONALARROW) ||
|
||||
IsToDraw(NOTATION_DOWNDIAGONALSTRIKE) ||
|
||||
IsToDraw(NOTATION_VERTICALSTRIKE) ||
|
||||
IsToDraw(NOTATION_CIRCLE) ||
|
||||
|
@ -398,6 +417,21 @@ nsMathMLmencloseFrame::PlaceInternal(nsRenderingContext& aRenderingContext,
|
|||
IsToDraw(NOTATION_CIRCLE))
|
||||
mBoundingMetrics.descent += padding;
|
||||
|
||||
///////////////
|
||||
// updiagonal arrow notation. We need enough space at the top right corner to
|
||||
// draw the arrow head.
|
||||
if (IsToDraw(NOTATION_UPDIAGONALARROW)) {
|
||||
// This is an estimate, see nsDisplayNotation::Paint for the exact head size
|
||||
nscoord arrowHeadSize = kArrowHeadSize * mRuleThickness;
|
||||
|
||||
// We want that the arrow shaft strikes the menclose content and that the
|
||||
// arrow head does not overlap with that content. Hence we add some space
|
||||
// on the right. We don't add space on the top but only ensure that the
|
||||
// ascent is large enough.
|
||||
dx_right = std::max(dx_right, arrowHeadSize);
|
||||
mBoundingMetrics.ascent = std::max(mBoundingMetrics.ascent, arrowHeadSize);
|
||||
}
|
||||
|
||||
///////////////
|
||||
// circle notation: we don't want the ellipse to overlap the enclosed
|
||||
// content. Hence, we need to increase the size of the bounding box by a
|
||||
|
@ -568,6 +602,7 @@ nsMathMLmencloseFrame::PlaceInternal(nsRenderingContext& aRenderingContext,
|
|||
IsToDraw(NOTATION_RIGHT) ||
|
||||
IsToDraw(NOTATION_LEFT) ||
|
||||
IsToDraw(NOTATION_UPDIAGONALSTRIKE) ||
|
||||
IsToDraw(NOTATION_UPDIAGONALARROW) ||
|
||||
IsToDraw(NOTATION_DOWNDIAGONALSTRIKE) ||
|
||||
IsToDraw(NOTATION_VERTICALSTRIKE) ||
|
||||
IsToDraw(NOTATION_CIRCLE) ||
|
||||
|
@ -578,6 +613,7 @@ nsMathMLmencloseFrame::PlaceInternal(nsRenderingContext& aRenderingContext,
|
|||
IsToDraw(NOTATION_RIGHT) ||
|
||||
IsToDraw(NOTATION_LEFT) ||
|
||||
IsToDraw(NOTATION_UPDIAGONALSTRIKE) ||
|
||||
IsToDraw(NOTATION_UPDIAGONALARROW) ||
|
||||
IsToDraw(NOTATION_DOWNDIAGONALSTRIKE) ||
|
||||
IsToDraw(NOTATION_VERTICALSTRIKE) ||
|
||||
IsToDraw(NOTATION_CIRCLE) ||
|
||||
|
@ -714,30 +750,63 @@ void nsDisplayNotation::Paint(nsDisplayListBuilder* aBuilder,
|
|||
|
||||
// change line width to mThickness
|
||||
gfxContext *gfxCtx = aCtx->ThebesContext();
|
||||
gfxFloat currentLineWidth = gfxCtx->CurrentLineWidth();
|
||||
gfxFloat e = presContext->AppUnitsToGfxUnits(mThickness);
|
||||
gfxCtx->Save();
|
||||
gfxCtx->SetLineWidth(e);
|
||||
|
||||
rect.Deflate(e / 2.0);
|
||||
|
||||
gfxCtx->NewPath();
|
||||
|
||||
switch(mType)
|
||||
{
|
||||
case NOTATION_CIRCLE:
|
||||
gfxCtx->NewPath();
|
||||
gfxCtx->Ellipse(rect.Center(), rect.Size());
|
||||
gfxCtx->Stroke();
|
||||
break;
|
||||
|
||||
case NOTATION_ROUNDEDBOX:
|
||||
gfxCtx->NewPath();
|
||||
gfxCtx->RoundedRectangle(rect, gfxCornerSizes(3 * e), true);
|
||||
gfxCtx->Stroke();
|
||||
break;
|
||||
|
||||
case NOTATION_UPDIAGONALSTRIKE:
|
||||
gfxCtx->NewPath();
|
||||
gfxCtx->Line(rect.BottomLeft(), rect.TopRight());
|
||||
gfxCtx->Stroke();
|
||||
break;
|
||||
|
||||
case NOTATION_DOWNDIAGONALSTRIKE:
|
||||
gfxCtx->NewPath();
|
||||
gfxCtx->Line(rect.TopLeft(), rect.BottomRight());
|
||||
gfxCtx->Stroke();
|
||||
break;
|
||||
|
||||
case NOTATION_UPDIAGONALARROW: {
|
||||
// Compute some parameters to draw the updiagonalarrow. The values below
|
||||
// are taken from MathJax's HTML-CSS output.
|
||||
gfxFloat W = rect.Width(); gfxFloat H = rect.Height();
|
||||
gfxFloat l = sqrt(W*W + H*H);
|
||||
gfxFloat f = gfxFloat(kArrowHeadSize) * e / l;
|
||||
gfxFloat w = W * f; gfxFloat h = H * f;
|
||||
|
||||
// Draw the arrow shaft
|
||||
gfxCtx->NewPath();
|
||||
gfxCtx->Line(rect.BottomLeft(), rect.TopRight() + gfxPoint(-.7*w, .7*h));
|
||||
gfxCtx->Stroke();
|
||||
|
||||
// Draw the arrow head
|
||||
gfxCtx->NewPath();
|
||||
gfxPoint p[] = {
|
||||
rect.TopRight(),
|
||||
rect.TopRight() + gfxPoint(-w -.4*h, std::max(-e / 2.0, h - .4*w)),
|
||||
rect.TopRight() + gfxPoint(-.7*w, .7*h),
|
||||
rect.TopRight() + gfxPoint(std::min(e / 2.0, -w + .4*h), h + .4*w),
|
||||
rect.TopRight()
|
||||
};
|
||||
gfxCtx->Polygon(p, sizeof(p));
|
||||
gfxCtx->Fill();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -745,10 +814,7 @@ void nsDisplayNotation::Paint(nsDisplayListBuilder* aBuilder,
|
|||
break;
|
||||
}
|
||||
|
||||
gfxCtx->Stroke();
|
||||
|
||||
// restore previous line width
|
||||
gfxCtx->SetLineWidth(currentLineWidth);
|
||||
gfxCtx->Restore();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -38,7 +38,8 @@ enum nsMencloseNotation
|
|||
NOTATION_UPDIAGONALSTRIKE = 0x100,
|
||||
NOTATION_DOWNDIAGONALSTRIKE = 0x200,
|
||||
NOTATION_VERTICALSTRIKE = 0x400,
|
||||
NOTATION_HORIZONTALSTRIKE = 0x800
|
||||
NOTATION_HORIZONTALSTRIKE = 0x800,
|
||||
NOTATION_UPDIAGONALARROW = 0x1000
|
||||
};
|
||||
|
||||
class nsMathMLmencloseFrame : public nsMathMLContainerFrame {
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><title>Updiagonalarrow</title></head>
|
||||
<body>
|
||||
|
||||
<p><math><menclose notation="updiagonalstrike"><mspace width="50px" height="50px"/></menclose></math></p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><title>Updiagonalarrow</title></head>
|
||||
<body>
|
||||
|
||||
<p><math><menclose><mspace width="50px" height="50px"/></menclose></math></p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -123,3 +123,4 @@ fails == whitespace-trim-4.html whitespace-trim-4-ref.html # Bug 787215
|
|||
== number-size-1.xhtml number-size-1-ref.xhtml
|
||||
== mathml-mmultiscript-base.html mathml-mmultiscript-base-ref.html
|
||||
== mathml-mmultiscript-mprescript.html mathml-mmultiscript-mprescript-ref.html
|
||||
!= menclose-1.html menclose-1-ref.html
|
||||
|
|
Загрузка…
Ссылка в новой задаче