mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 668204 - Merge nsMathMLmunderFrame and nsMathMLmoverFrame into nsMathMLmunderoverFrame. r=karlt
This commit is contained in:
parent
c8586cbbf2
commit
c9d5ac8edc
@ -4646,8 +4646,8 @@ nsCSSFrameConstructor::FindMathMLData(Element* aElement,
|
||||
SIMPLE_MATHML_CREATE(msup_, NS_NewMathMLmsupFrame),
|
||||
SIMPLE_MATHML_CREATE(msub_, NS_NewMathMLmsubFrame),
|
||||
SIMPLE_MATHML_CREATE(msubsup_, NS_NewMathMLmsubsupFrame),
|
||||
SIMPLE_MATHML_CREATE(munder_, NS_NewMathMLmunderFrame),
|
||||
SIMPLE_MATHML_CREATE(mover_, NS_NewMathMLmoverFrame),
|
||||
SIMPLE_MATHML_CREATE(munder_, NS_NewMathMLmunderoverFrame),
|
||||
SIMPLE_MATHML_CREATE(mover_, NS_NewMathMLmunderoverFrame),
|
||||
SIMPLE_MATHML_CREATE(munderover_, NS_NewMathMLmunderoverFrame),
|
||||
SIMPLE_MATHML_CREATE(mphantom_, NS_NewMathMLmphantomFrame),
|
||||
SIMPLE_MATHML_CREATE(mpadded_, NS_NewMathMLmpaddedFrame),
|
||||
|
@ -76,8 +76,6 @@ CPPSRCS = nsMathMLChar.cpp \
|
||||
nsMathMLmsubsupFrame.cpp \
|
||||
nsMathMLmmultiscriptsFrame.cpp \
|
||||
nsMathMLmtableFrame.cpp \
|
||||
nsMathMLmunderFrame.cpp \
|
||||
nsMathMLmoverFrame.cpp \
|
||||
nsMathMLmunderoverFrame.cpp \
|
||||
nsMathMLmpaddedFrame.cpp \
|
||||
nsMathMLmspaceFrame.cpp \
|
||||
|
@ -56,8 +56,6 @@ nsIFrame* NS_NewMathMLmfracFrame(nsIPresShell* aPresShell, nsStyleContext* aCont
|
||||
nsIFrame* NS_NewMathMLmsubFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
nsIFrame* NS_NewMathMLmsupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
nsIFrame* NS_NewMathMLmsubsupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
nsIFrame* NS_NewMathMLmunderFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
nsIFrame* NS_NewMathMLmoverFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
nsIFrame* NS_NewMathMLmunderoverFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
nsIFrame* NS_NewMathMLmmultiscriptsFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
nsIFrame* NS_NewMathMLmstyleFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
|
@ -1,409 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public 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 Queensland.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Roger B. Sidje <rbs@maths.uq.edu.au>
|
||||
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
|
||||
* Shyjan Mahamud <mahamud@cs.cmu.edu>
|
||||
* Pierre Phaneuf <pp@ludusdesign.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsFrame.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsStyleContext.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsRenderingContext.h"
|
||||
|
||||
#include "nsMathMLmoverFrame.h"
|
||||
#include "nsMathMLmsupFrame.h"
|
||||
|
||||
//
|
||||
// <mover> -- attach an overscript to a base - implementation
|
||||
//
|
||||
|
||||
nsIFrame*
|
||||
NS_NewMathMLmoverFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
|
||||
{
|
||||
return new (aPresShell) nsMathMLmoverFrame(aContext);
|
||||
}
|
||||
|
||||
NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmoverFrame)
|
||||
|
||||
nsMathMLmoverFrame::~nsMathMLmoverFrame()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLmoverFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType)
|
||||
{
|
||||
if (nsGkAtoms::accent_ == aAttribute) {
|
||||
// When we have automatic data to update within ourselves, we ask our
|
||||
// parent to re-layout its children
|
||||
return ReLayoutChildren(mParent);
|
||||
}
|
||||
|
||||
return nsMathMLContainerFrame::
|
||||
AttributeChanged(aNameSpaceID, aAttribute, aModType);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLmoverFrame::UpdatePresentationData(PRUint32 aFlagsValues,
|
||||
PRUint32 aFlagsToUpdate)
|
||||
{
|
||||
nsMathMLContainerFrame::UpdatePresentationData(aFlagsValues, aFlagsToUpdate);
|
||||
// disable the stretch-all flag if we are going to act like a superscript
|
||||
if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
|
||||
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
|
||||
mPresentationData.flags &= ~NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
|
||||
}
|
||||
else {
|
||||
mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLmoverFrame::UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex,
|
||||
PRInt32 aLastIndex,
|
||||
PRUint32 aFlagsValues,
|
||||
PRUint32 aFlagsToUpdate)
|
||||
{
|
||||
// mover is special... The REC says:
|
||||
// Within overscript, <mover> always sets displaystyle to "false",
|
||||
// but increments scriptlevel by 1 only when accent is "false".
|
||||
// This means that
|
||||
// 1. don't allow displaystyle to change in the overscript
|
||||
// 2. if the value of the accent is changed, we need to recompute the
|
||||
// scriptlevel of the overscript. The problem is that the accent
|
||||
// can change in the <mo> deep down the embellished hierarchy
|
||||
|
||||
// Do #1 here, never allow displaystyle to be changed in the overscript
|
||||
PRInt32 index = 0;
|
||||
nsIFrame* childFrame = mFrames.FirstChild();
|
||||
while (childFrame) {
|
||||
if ((index >= aFirstIndex) &&
|
||||
((aLastIndex <= 0) || ((aLastIndex > 0) && (index <= aLastIndex)))) {
|
||||
if (index > 0) {
|
||||
// disable the flag
|
||||
aFlagsToUpdate &= ~NS_MATHML_DISPLAYSTYLE;
|
||||
aFlagsValues &= ~NS_MATHML_DISPLAYSTYLE;
|
||||
}
|
||||
PropagatePresentationDataFor(childFrame, aFlagsValues, aFlagsToUpdate);
|
||||
}
|
||||
index++;
|
||||
childFrame = childFrame->GetNextSibling();
|
||||
}
|
||||
return NS_OK;
|
||||
|
||||
// For #2, changing the accent attribute will trigger a re-build of
|
||||
// all automatic data in the embellished hierarchy
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLmoverFrame::InheritAutomaticData(nsIFrame* aParent)
|
||||
{
|
||||
// let the base class get the default from our parent
|
||||
nsMathMLContainerFrame::InheritAutomaticData(aParent);
|
||||
|
||||
mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLmoverFrame::TransmitAutomaticData()
|
||||
{
|
||||
// At this stage, all our children are in sync and we can fully
|
||||
// resolve our own mEmbellishData struct
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
/* The REC says:
|
||||
The default value of accent is false, unless overscript
|
||||
is an <mo> element or an embellished operator. If overscript is
|
||||
an <mo> element, the value of its accent attribute is used as
|
||||
the default value of accent. If overscript is an embellished
|
||||
operator, the accent attribute of the <mo> element at its
|
||||
core is used as the default value. As with all attributes, an
|
||||
explicitly given value overrides the default.
|
||||
|
||||
XXX The winner is the outermost in conflicting settings like these:
|
||||
<mover accent='true'>
|
||||
<mi>...</mi>
|
||||
<mo accent='false'> ... </mo>
|
||||
</mover>
|
||||
*/
|
||||
|
||||
nsIFrame* overscriptFrame = nsnull;
|
||||
nsIFrame* baseFrame = mFrames.FirstChild();
|
||||
if (baseFrame)
|
||||
overscriptFrame = baseFrame->GetNextSibling();
|
||||
|
||||
// if our base is an embellished operator, let its state bubble to us (in particular,
|
||||
// this is where we get the flag for NS_MATHML_EMBELLISH_MOVABLELIMITS). Our flags
|
||||
// are reset to the default values of false if the base frame isn't embellished.
|
||||
mPresentationData.baseFrame = baseFrame;
|
||||
GetEmbellishDataFrom(baseFrame, mEmbellishData);
|
||||
|
||||
// The default value of accent is false, unless the overscript is embellished
|
||||
// and its core <mo> is an accent
|
||||
nsEmbellishData embellishData;
|
||||
GetEmbellishDataFrom(overscriptFrame, embellishData);
|
||||
if (NS_MATHML_EMBELLISH_IS_ACCENT(embellishData.flags))
|
||||
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTOVER;
|
||||
else
|
||||
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTOVER;
|
||||
|
||||
// if we have an accent attribute, it overrides what the overscript said
|
||||
nsAutoString value;
|
||||
if (GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::accent_,
|
||||
value)) {
|
||||
if (value.EqualsLiteral("true")) {
|
||||
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTOVER;
|
||||
} else if (value.EqualsLiteral("false")) {
|
||||
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTOVER;
|
||||
}
|
||||
}
|
||||
|
||||
// disable the stretch-all flag if we are going to act like a superscript
|
||||
if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
|
||||
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags))
|
||||
mPresentationData.flags &= ~NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
|
||||
|
||||
// Now transmit any change that we want to our children so that they
|
||||
// can update their mPresentationData structs
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
/* The REC says:
|
||||
Within overscript, <mover> always sets displaystyle to "false",
|
||||
but increments scriptlevel by 1 only when accent is "false".
|
||||
|
||||
The TeXBook treats 'over' like a superscript, so p.141 or Rule 13a
|
||||
say it shouldn't be compressed. However, The TeXBook says
|
||||
that math accents and \overline change uncramped styles to their
|
||||
cramped counterparts.
|
||||
*/
|
||||
SetIncrementScriptLevel(1, !NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags));
|
||||
PRUint32 compress = NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)
|
||||
? NS_MATHML_COMPRESSED : 0;
|
||||
PropagatePresentationDataFor(overscriptFrame,
|
||||
~NS_MATHML_DISPLAYSTYLE | compress,
|
||||
NS_MATHML_DISPLAYSTYLE | compress);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
The REC says:
|
||||
* If the base is an operator with movablelimits="true" (or an embellished
|
||||
operator whose <mo> element core has movablelimits="true"), and
|
||||
displaystyle="false", then overscript is drawn in a superscript
|
||||
position. In this case, the accent attribute is ignored. This is
|
||||
often used for limits on symbols such as ∑.
|
||||
|
||||
i.e.:
|
||||
if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
|
||||
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
|
||||
// place like superscript
|
||||
}
|
||||
else {
|
||||
// place like overscript
|
||||
}
|
||||
*/
|
||||
|
||||
/* virtual */ nsresult
|
||||
nsMathMLmoverFrame::Place(nsRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize)
|
||||
{
|
||||
if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
|
||||
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
|
||||
// place like superscript
|
||||
return nsMathMLmsupFrame::PlaceSuperScript(PresContext(),
|
||||
aRenderingContext,
|
||||
aPlaceOrigin,
|
||||
aDesiredSize,
|
||||
this, 0, nsPresContext::CSSPointsToAppUnits(0.5f));
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Get the children's desired sizes
|
||||
|
||||
nsBoundingMetrics bmBase, bmOver;
|
||||
nsHTMLReflowMetrics baseSize;
|
||||
nsHTMLReflowMetrics overSize;
|
||||
nsIFrame* overFrame = nsnull;
|
||||
nsIFrame* baseFrame = mFrames.FirstChild();
|
||||
if (baseFrame)
|
||||
overFrame = baseFrame->GetNextSibling();
|
||||
if (!baseFrame || !overFrame || overFrame->GetNextSibling()) {
|
||||
// report an error, encourage people to get their markups in order
|
||||
return ReflowError(aRenderingContext, aDesiredSize);
|
||||
}
|
||||
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
|
||||
GetReflowAndBoundingMetricsFor(overFrame, overSize, bmOver);
|
||||
|
||||
nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1);
|
||||
|
||||
////////////////////
|
||||
// Place Children
|
||||
|
||||
aRenderingContext.SetFont(GetStyleFont()->mFont,
|
||||
PresContext()->GetUserFontSet());
|
||||
nsFontMetrics* fm = aRenderingContext.FontMetrics();
|
||||
|
||||
nscoord xHeight = fm->XHeight();
|
||||
|
||||
nscoord ruleThickness;
|
||||
GetRuleThickness (aRenderingContext, fm, ruleThickness);
|
||||
|
||||
// there are 2 different types of placement depending on
|
||||
// whether we want an accented overscript or not
|
||||
|
||||
nscoord correction = 0;
|
||||
GetItalicCorrection (bmBase, correction);
|
||||
|
||||
nscoord delta1 = 0; // gap between base and overscript
|
||||
nscoord delta2 = 0; // extra space above overscript
|
||||
if (!NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)) {
|
||||
// Rule 13a, App. G, TeXbook
|
||||
nscoord bigOpSpacing1, bigOpSpacing3, bigOpSpacing5, dummy;
|
||||
GetBigOpSpacings (fm,
|
||||
bigOpSpacing1, dummy,
|
||||
bigOpSpacing3, dummy,
|
||||
bigOpSpacing5);
|
||||
delta1 = NS_MAX(bigOpSpacing1, (bigOpSpacing3 - bmOver.descent));
|
||||
delta2 = bigOpSpacing5;
|
||||
|
||||
// XXX This is not a TeX rule...
|
||||
// delta1 (as computed above) can become really big when bmOver.descent is
|
||||
// negative, e.g., if the content is &OverBar. In such case, we use the height
|
||||
if (bmOver.descent < 0)
|
||||
delta1 = NS_MAX(bigOpSpacing1, (bigOpSpacing3 - (bmOver.ascent + bmOver.descent)));
|
||||
}
|
||||
else {
|
||||
// Rule 12, App. G, TeXbook
|
||||
// We are going to modify this rule to make it more general.
|
||||
// The idea behind Rule 12 in the TeXBook is to keep the accent
|
||||
// as close to the base as possible, while ensuring that the
|
||||
// distance between the *baseline* of the accent char and
|
||||
// the *baseline* of the base is atleast x-height.
|
||||
// The idea is that for normal use, we would like all the accents
|
||||
// on a line to line up atleast x-height above the baseline
|
||||
// if possible.
|
||||
// When the ascent of the base is >= x-height,
|
||||
// the baseline of the accent char is placed just above the base
|
||||
// (specifically, the baseline of the accent char is placed
|
||||
// above the baseline of the base by the ascent of the base).
|
||||
// For ease of implementation,
|
||||
// this assumes that the font-designer designs accents
|
||||
// in such a way that the bottom of the accent is atleast x-height
|
||||
// above its baseline, otherwise there will be collisions
|
||||
// with the base. Also there should be proper padding between
|
||||
// the bottom of the accent char and its baseline.
|
||||
// The above rule may not be obvious from a first
|
||||
// reading of rule 12 in the TeXBook !!!
|
||||
// The mathml <mover> tag can use accent chars that
|
||||
// do not follow this convention. So we modify TeX's rule
|
||||
// so that TeX's rule gets subsumed for accents that follow
|
||||
// TeX's convention,
|
||||
// while also allowing accents that do not follow the convention :
|
||||
// we try to keep the *bottom* of the accent char atleast x-height
|
||||
// from the baseline of the base char. we also slap on an extra
|
||||
// padding between the accent and base chars.
|
||||
delta1 = ruleThickness + onePixel/2; // we have at least the padding
|
||||
if (bmBase.ascent < xHeight) {
|
||||
// also ensure at least x-height above the baseline of the base
|
||||
delta1 += xHeight - bmBase.ascent;
|
||||
}
|
||||
delta2 = ruleThickness;
|
||||
}
|
||||
// empty over?
|
||||
if (!(bmOver.ascent + bmOver.descent)) delta1 = 0;
|
||||
|
||||
nscoord dxBase, dxOver = 0;
|
||||
|
||||
// Ad-hoc - This is to override fonts which have ready-made _accent_
|
||||
// glyphs with negative lbearing and rbearing. We want to position
|
||||
// the overscript ourselves
|
||||
nscoord overWidth = bmOver.width;
|
||||
if (!overWidth && (bmOver.rightBearing - bmOver.leftBearing > 0)) {
|
||||
overWidth = bmOver.rightBearing - bmOver.leftBearing;
|
||||
dxOver = -bmOver.leftBearing;
|
||||
}
|
||||
|
||||
if (NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)) {
|
||||
mBoundingMetrics.width = bmBase.width;
|
||||
dxOver += correction + (mBoundingMetrics.width - overWidth)/2;
|
||||
}
|
||||
else {
|
||||
mBoundingMetrics.width = NS_MAX(bmBase.width, overWidth);
|
||||
dxOver += correction/2 + (mBoundingMetrics.width - overWidth)/2;
|
||||
}
|
||||
dxBase = (mBoundingMetrics.width - bmBase.width) / 2;
|
||||
|
||||
mBoundingMetrics.ascent =
|
||||
bmOver.ascent + bmOver.descent + delta1 + bmBase.ascent;
|
||||
mBoundingMetrics.descent = bmBase.descent;
|
||||
mBoundingMetrics.leftBearing =
|
||||
NS_MIN(dxBase + bmBase.leftBearing, dxOver + bmOver.leftBearing);
|
||||
mBoundingMetrics.rightBearing =
|
||||
NS_MAX(dxBase + bmBase.rightBearing, dxOver + bmOver.rightBearing);
|
||||
|
||||
aDesiredSize.ascent =
|
||||
NS_MAX(mBoundingMetrics.ascent + delta2,
|
||||
overSize.ascent + bmOver.descent + delta1 + bmBase.ascent);
|
||||
aDesiredSize.height = aDesiredSize.ascent +
|
||||
baseSize.height - baseSize.ascent;
|
||||
aDesiredSize.width = mBoundingMetrics.width;
|
||||
aDesiredSize.mBoundingMetrics = mBoundingMetrics;
|
||||
|
||||
mReference.x = 0;
|
||||
mReference.y = aDesiredSize.ascent;
|
||||
|
||||
if (aPlaceOrigin) {
|
||||
// place base
|
||||
nscoord dy = aDesiredSize.ascent - baseSize.ascent;
|
||||
FinishReflowChild (baseFrame, PresContext(), nsnull, baseSize, dxBase, dy, 0);
|
||||
// place overscript
|
||||
dy = aDesiredSize.ascent -
|
||||
mBoundingMetrics.ascent + bmOver.ascent - overSize.ascent;
|
||||
FinishReflowChild (overFrame, PresContext(), nsnull, overSize, dxOver, dy, 0);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public 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 Queensland.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Roger B. Sidje <rbs@maths.uq.edu.au>
|
||||
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
|
||||
* Shyjan Mahamud <mahamud@cs.cmu.edu>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsMathMLmoverFrame_h___
|
||||
#define nsMathMLmoverFrame_h___
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsMathMLContainerFrame.h"
|
||||
|
||||
//
|
||||
// <mover> -- attach an overscript to a base
|
||||
//
|
||||
|
||||
class nsMathMLmoverFrame : public nsMathMLContainerFrame {
|
||||
public:
|
||||
NS_DECL_FRAMEARENA_HELPERS
|
||||
|
||||
friend nsIFrame* NS_NewMathMLmoverFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
|
||||
virtual nsresult
|
||||
Place(nsRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize);
|
||||
|
||||
NS_IMETHOD
|
||||
InheritAutomaticData(nsIFrame* aParent);
|
||||
|
||||
NS_IMETHOD
|
||||
TransmitAutomaticData();
|
||||
|
||||
NS_IMETHOD
|
||||
UpdatePresentationData(PRUint32 aFlagsValues,
|
||||
PRUint32 aFlagsToUpdate);
|
||||
|
||||
NS_IMETHOD
|
||||
UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex,
|
||||
PRInt32 aLastIndex,
|
||||
PRUint32 aFlagsValues,
|
||||
PRUint32 aFlagsToUpdate);
|
||||
|
||||
NS_IMETHOD
|
||||
AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType);
|
||||
|
||||
protected:
|
||||
nsMathMLmoverFrame(nsStyleContext* aContext) : nsMathMLContainerFrame(aContext) {}
|
||||
virtual ~nsMathMLmoverFrame();
|
||||
|
||||
virtual PRIntn GetSkipSides() const { return 0; }
|
||||
};
|
||||
|
||||
|
||||
#endif /* nsMathMLmoverFrame_h___ */
|
@ -1,369 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public 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 Queensland.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Roger B. Sidje <rbs@maths.uq.edu.au>
|
||||
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
|
||||
* Shyjan Mahamud <mahamud@cs.cmu.edu>
|
||||
* Pierre Phaneuf <pp@ludusdesign.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsFrame.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsStyleContext.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsRenderingContext.h"
|
||||
|
||||
#include "nsMathMLmunderFrame.h"
|
||||
#include "nsMathMLmsubFrame.h"
|
||||
|
||||
//
|
||||
// <munder> -- attach an underscript to a base - implementation
|
||||
//
|
||||
|
||||
nsIFrame*
|
||||
NS_NewMathMLmunderFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
|
||||
{
|
||||
return new (aPresShell) nsMathMLmunderFrame(aContext);
|
||||
}
|
||||
|
||||
NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmunderFrame)
|
||||
|
||||
nsMathMLmunderFrame::~nsMathMLmunderFrame()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLmunderFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType)
|
||||
{
|
||||
if (nsGkAtoms::accentunder_ == aAttribute) {
|
||||
// When we have automatic data to update within ourselves, we ask our
|
||||
// parent to re-layout its children
|
||||
return ReLayoutChildren(mParent);
|
||||
}
|
||||
|
||||
return nsMathMLContainerFrame::
|
||||
AttributeChanged(aNameSpaceID, aAttribute, aModType);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLmunderFrame::UpdatePresentationData(PRUint32 aFlagsValues,
|
||||
PRUint32 aFlagsToUpdate)
|
||||
{
|
||||
nsMathMLContainerFrame::UpdatePresentationData(aFlagsValues, aFlagsToUpdate);
|
||||
// disable the stretch-all flag if we are going to act like a subscript
|
||||
if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
|
||||
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
|
||||
mPresentationData.flags &= ~NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
|
||||
}
|
||||
else {
|
||||
mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLmunderFrame::UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex,
|
||||
PRInt32 aLastIndex,
|
||||
PRUint32 aFlagsValues,
|
||||
PRUint32 aFlagsToUpdate)
|
||||
{
|
||||
// munder is special... The REC says:
|
||||
// Within underscript, <munder> always sets displaystyle to "false",
|
||||
// but increments scriptlevel by 1 only when accentunder is "false".
|
||||
// This means that
|
||||
// 1. don't allow displaystyle to change in the underscript
|
||||
// 2. if the value of the accent is changed, we need to recompute the
|
||||
// scriptlevel of the underscript. The problem is that the accent
|
||||
// can change in the <mo> deep down the embellished hierarchy
|
||||
|
||||
// Do #1 here, never allow displaystyle to be changed in the underscript
|
||||
PRInt32 index = 0;
|
||||
nsIFrame* childFrame = mFrames.FirstChild();
|
||||
while (childFrame) {
|
||||
if ((index >= aFirstIndex) &&
|
||||
((aLastIndex <= 0) || ((aLastIndex > 0) && (index <= aLastIndex)))) {
|
||||
if (index > 0) {
|
||||
// disable the flag
|
||||
aFlagsToUpdate &= ~NS_MATHML_DISPLAYSTYLE;
|
||||
aFlagsValues &= ~NS_MATHML_DISPLAYSTYLE;
|
||||
}
|
||||
PropagatePresentationDataFor(childFrame, aFlagsValues, aFlagsToUpdate);
|
||||
}
|
||||
index++;
|
||||
childFrame = childFrame->GetNextSibling();
|
||||
}
|
||||
return NS_OK;
|
||||
|
||||
// For #2, changing the accent attribute will trigger a re-build of
|
||||
// all automatic data in the embellished hierarchy
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLmunderFrame::InheritAutomaticData(nsIFrame* aParent)
|
||||
{
|
||||
// let the base class get the default from our parent
|
||||
nsMathMLContainerFrame::InheritAutomaticData(aParent);
|
||||
|
||||
mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLmunderFrame::TransmitAutomaticData()
|
||||
{
|
||||
// At this stage, all our children are in sync and we can fully
|
||||
// resolve our own mEmbellishData struct
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
/* The REC says:
|
||||
The default value of accentunder is false, unless underscript
|
||||
is an <mo> element or an embellished operator. If underscript is
|
||||
an <mo> element, the value of its accent attribute is used as the
|
||||
default value of accentunder. If underscript is an embellished
|
||||
operator, the accent attribute of the <mo> element at its
|
||||
core is used as the default value. As with all attributes, an
|
||||
explicitly given value overrides the default.
|
||||
|
||||
XXX The winner is the outermost setting in conflicting settings like these:
|
||||
<munder accent='true'>
|
||||
<mi>...</mi>
|
||||
<mo accent='false'> ... </mo>
|
||||
</munder>
|
||||
*/
|
||||
|
||||
nsIFrame* underscriptFrame = nsnull;
|
||||
nsIFrame* baseFrame = mFrames.FirstChild();
|
||||
if (baseFrame)
|
||||
underscriptFrame = baseFrame->GetNextSibling();
|
||||
|
||||
// if our base is an embellished operator, let its state bubble to us (in particular,
|
||||
// this is where we get the flag for NS_MATHML_EMBELLISH_MOVABLELIMITS). Our flags
|
||||
// are reset to the default values of false if the base frame isn't embellished.
|
||||
mPresentationData.baseFrame = baseFrame;
|
||||
GetEmbellishDataFrom(baseFrame, mEmbellishData);
|
||||
|
||||
// The default value of accentunder is false, unless the underscript is embellished
|
||||
// and its core <mo> is an accent
|
||||
nsEmbellishData embellishData;
|
||||
GetEmbellishDataFrom(underscriptFrame, embellishData);
|
||||
if (NS_MATHML_EMBELLISH_IS_ACCENT(embellishData.flags))
|
||||
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTUNDER;
|
||||
else
|
||||
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTUNDER;
|
||||
|
||||
// if we have an accentunder attribute, it overrides what the underscript said
|
||||
nsAutoString value;
|
||||
if (GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::accentunder_,
|
||||
value)) {
|
||||
if (value.EqualsLiteral("true")) {
|
||||
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTUNDER;
|
||||
} else if (value.EqualsLiteral("false")) {
|
||||
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTUNDER;
|
||||
}
|
||||
}
|
||||
|
||||
// disable the stretch-all flag if we are going to act like a superscript
|
||||
if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
|
||||
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags))
|
||||
mPresentationData.flags &= ~NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
|
||||
|
||||
// Now transmit any change that we want to our children so that they
|
||||
// can update their mPresentationData structs
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
/* The REC says:
|
||||
Within underscript, <munder> always sets displaystyle to "false",
|
||||
but increments scriptlevel by 1 only when accentunder is "false".
|
||||
|
||||
The TeXBook treats 'under' like a subscript, so p.141 or Rule 13a
|
||||
say it should be compressed
|
||||
*/
|
||||
SetIncrementScriptLevel(1, !NS_MATHML_EMBELLISH_IS_ACCENTUNDER(mEmbellishData.flags));
|
||||
PropagatePresentationDataFor(underscriptFrame,
|
||||
~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED,
|
||||
NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
The REC says:
|
||||
* If the base is an operator with movablelimits="true" (or
|
||||
an embellished operator whose <mo> element core has
|
||||
movablelimits="true"), and displaystyle="false", then
|
||||
underscript is drawn in a subscript position. In this case,
|
||||
the accentunder attribute is ignored. This is often used
|
||||
for limits on symbols such as ∑.
|
||||
|
||||
i.e.,:
|
||||
if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
|
||||
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
|
||||
// place like subscript
|
||||
}
|
||||
else {
|
||||
// place like underscript
|
||||
}
|
||||
*/
|
||||
|
||||
/* virtual */ nsresult
|
||||
nsMathMLmunderFrame::Place(nsRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize)
|
||||
{
|
||||
if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
|
||||
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
|
||||
// place like subscript
|
||||
return nsMathMLmsubFrame::PlaceSubScript(PresContext(),
|
||||
aRenderingContext,
|
||||
aPlaceOrigin,
|
||||
aDesiredSize,
|
||||
this, 0, nsPresContext::CSSPointsToAppUnits(0.5f));
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Get the children's desired sizes
|
||||
|
||||
nsBoundingMetrics bmBase, bmUnder;
|
||||
nsHTMLReflowMetrics baseSize;
|
||||
nsHTMLReflowMetrics underSize;
|
||||
nsIFrame* underFrame = nsnull;
|
||||
nsIFrame* baseFrame = mFrames.FirstChild();
|
||||
if (baseFrame)
|
||||
underFrame = baseFrame->GetNextSibling();
|
||||
if (!baseFrame || !underFrame || underFrame->GetNextSibling()) {
|
||||
// report an error, encourage people to get their markups in order
|
||||
return ReflowError(aRenderingContext, aDesiredSize);
|
||||
}
|
||||
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
|
||||
GetReflowAndBoundingMetricsFor(underFrame, underSize, bmUnder);
|
||||
|
||||
nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1);
|
||||
|
||||
////////////////////
|
||||
// Place Children
|
||||
|
||||
aRenderingContext.SetFont(GetStyleFont()->mFont,
|
||||
PresContext()->GetUserFontSet());
|
||||
nsFontMetrics* fm = aRenderingContext.FontMetrics();
|
||||
|
||||
nscoord ruleThickness;
|
||||
GetRuleThickness (aRenderingContext, fm, ruleThickness);
|
||||
|
||||
// there are 2 different types of placement depending on
|
||||
// whether we want an accented under or not
|
||||
|
||||
nscoord correction = 0;
|
||||
GetItalicCorrection (bmBase, correction);
|
||||
|
||||
nscoord delta1 = 0; // gap between base and underscript
|
||||
nscoord delta2 = 0; // extra space beneath underscript
|
||||
if (!NS_MATHML_EMBELLISH_IS_ACCENTUNDER(mEmbellishData.flags)) {
|
||||
// Rule 13a, App. G, TeXbook
|
||||
nscoord bigOpSpacing2, bigOpSpacing4, bigOpSpacing5, dummy;
|
||||
GetBigOpSpacings (fm,
|
||||
dummy, bigOpSpacing2,
|
||||
dummy, bigOpSpacing4,
|
||||
bigOpSpacing5);
|
||||
delta1 = NS_MAX(bigOpSpacing2, (bigOpSpacing4 - bmUnder.ascent));
|
||||
delta2 = bigOpSpacing5;
|
||||
}
|
||||
else {
|
||||
// No corresponding rule in TeXbook - we are on our own here
|
||||
// XXX tune the gap delta between base and underscript
|
||||
|
||||
// Should we use Rule 10 like \underline does?
|
||||
delta1 = ruleThickness + onePixel/2;
|
||||
delta2 = ruleThickness;
|
||||
}
|
||||
// empty under?
|
||||
if (!(bmUnder.ascent + bmUnder.descent)) delta1 = 0;
|
||||
|
||||
nscoord dxBase, dxUnder = 0;
|
||||
|
||||
// Width of non-spacing marks is zero so use left and right bearing.
|
||||
nscoord underWidth = bmUnder.width;
|
||||
if (!underWidth) {
|
||||
underWidth = bmUnder.rightBearing - bmUnder.leftBearing;
|
||||
dxUnder = -bmUnder.leftBearing;
|
||||
}
|
||||
|
||||
nscoord maxWidth = NS_MAX(bmBase.width, underWidth);
|
||||
if (NS_MATHML_EMBELLISH_IS_ACCENTUNDER(mEmbellishData.flags)) {
|
||||
dxUnder += (maxWidth - underWidth)/2;
|
||||
}
|
||||
else {
|
||||
dxUnder += -correction/2 + (maxWidth - underWidth)/2;
|
||||
}
|
||||
dxBase = (maxWidth - bmBase.width)/2;
|
||||
|
||||
mBoundingMetrics.width =
|
||||
NS_MAX(dxBase + bmBase.width, dxUnder + bmUnder.width);
|
||||
mBoundingMetrics.ascent = bmBase.ascent;
|
||||
mBoundingMetrics.descent =
|
||||
bmBase.descent + delta1 + bmUnder.ascent + bmUnder.descent;
|
||||
mBoundingMetrics.leftBearing =
|
||||
NS_MIN(dxBase + bmBase.leftBearing, dxUnder + bmUnder.leftBearing);
|
||||
mBoundingMetrics.rightBearing =
|
||||
NS_MAX(dxBase + bmBase.rightBearing, dxUnder + bmUnder.rightBearing);
|
||||
|
||||
aDesiredSize.ascent = baseSize.ascent;
|
||||
aDesiredSize.height = aDesiredSize.ascent +
|
||||
NS_MAX(mBoundingMetrics.descent + delta2,
|
||||
bmBase.descent + delta1 + bmUnder.ascent +
|
||||
underSize.height - underSize.ascent);
|
||||
aDesiredSize.width = mBoundingMetrics.width;
|
||||
aDesiredSize.mBoundingMetrics = mBoundingMetrics;
|
||||
|
||||
mReference.x = 0;
|
||||
mReference.y = aDesiredSize.ascent;
|
||||
|
||||
if (aPlaceOrigin) {
|
||||
nscoord dy = 0;
|
||||
// place base
|
||||
FinishReflowChild(baseFrame, PresContext(), nsnull, baseSize, dxBase, dy, 0);
|
||||
// place underscript
|
||||
dy = aDesiredSize.ascent + mBoundingMetrics.descent - bmUnder.descent - underSize.ascent;
|
||||
FinishReflowChild(underFrame, PresContext(), nsnull, underSize, dxUnder, dy, 0);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1,90 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public 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 Queensland.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Roger B. Sidje <rbs@maths.uq.edu.au>
|
||||
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
|
||||
* Shyjan Mahamud <mahamud@cs.cmu.edu>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsMathMLmunderFrame_h___
|
||||
#define nsMathMLmunderFrame_h___
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsMathMLContainerFrame.h"
|
||||
|
||||
//
|
||||
// <munder> -- attach an underscript to a base
|
||||
//
|
||||
|
||||
class nsMathMLmunderFrame : public nsMathMLContainerFrame {
|
||||
public:
|
||||
NS_DECL_FRAMEARENA_HELPERS
|
||||
|
||||
friend nsIFrame* NS_NewMathMLmunderFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
|
||||
virtual nsresult
|
||||
Place(nsRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize);
|
||||
|
||||
NS_IMETHOD
|
||||
InheritAutomaticData(nsIFrame* aParent);
|
||||
|
||||
NS_IMETHOD
|
||||
TransmitAutomaticData();
|
||||
|
||||
NS_IMETHOD
|
||||
UpdatePresentationData(PRUint32 aFlagsValues,
|
||||
PRUint32 aFlagsToUpdate);
|
||||
|
||||
NS_IMETHOD
|
||||
UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex,
|
||||
PRInt32 aLastIndex,
|
||||
PRUint32 aFlagsValues,
|
||||
PRUint32 aFlagsToUpdate);
|
||||
|
||||
NS_IMETHOD
|
||||
AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType);
|
||||
|
||||
protected:
|
||||
nsMathMLmunderFrame(nsStyleContext* aContext) : nsMathMLContainerFrame(aContext) {}
|
||||
virtual ~nsMathMLmunderFrame();
|
||||
|
||||
virtual PRIntn GetSkipSides() const { return 0; }
|
||||
};
|
||||
|
||||
#endif /* nsMathMLmunderFrame_h___ */
|
@ -50,9 +50,13 @@
|
||||
|
||||
#include "nsMathMLmunderoverFrame.h"
|
||||
#include "nsMathMLmsubsupFrame.h"
|
||||
#include "nsMathMLmsupFrame.h"
|
||||
#include "nsMathMLmsubFrame.h"
|
||||
|
||||
//
|
||||
// <munderover> -- attach an underscript-overscript pair to a base - implementation
|
||||
// <mover> -- attach an overscript to a base - implementation
|
||||
// <munder> -- attach an underscript to a base - implementation
|
||||
//
|
||||
|
||||
nsIFrame*
|
||||
@ -162,6 +166,22 @@ nsMathMLmunderoverFrame::TransmitAutomaticData()
|
||||
/*
|
||||
The REC says:
|
||||
|
||||
As regards munder (respectively mover) :
|
||||
The default value of accentunder is false, unless underscript
|
||||
is an <mo> element or an embellished operator. If underscript is
|
||||
an <mo> element, the value of its accent attribute is used as the
|
||||
default value of accentunder. If underscript is an embellished
|
||||
operator, the accent attribute of the <mo> element at its
|
||||
core is used as the default value. As with all attributes, an
|
||||
explicitly given value overrides the default.
|
||||
|
||||
XXX The winner is the outermost setting in conflicting settings like these:
|
||||
<munder accentunder='true'>
|
||||
<mi>...</mi>
|
||||
<mo accentunder='false'> ... </mo>
|
||||
</munder>
|
||||
|
||||
As regards munderover:
|
||||
The accent and accentunder attributes have the same effect as
|
||||
the attributes with the same names on <mover> and <munder>,
|
||||
respectively. Their default values are also computed in the
|
||||
@ -173,11 +193,23 @@ nsMathMLmunderoverFrame::TransmitAutomaticData()
|
||||
nsIFrame* overscriptFrame = nsnull;
|
||||
nsIFrame* underscriptFrame = nsnull;
|
||||
nsIFrame* baseFrame = mFrames.FirstChild();
|
||||
if (baseFrame)
|
||||
underscriptFrame = baseFrame->GetNextSibling();
|
||||
if (underscriptFrame)
|
||||
nsIAtom* tag = mContent->Tag();
|
||||
|
||||
if (baseFrame) {
|
||||
if (tag == nsGkAtoms::munder_ ||
|
||||
tag == nsGkAtoms::munderover_) {
|
||||
underscriptFrame = baseFrame->GetNextSibling();
|
||||
} else {
|
||||
NS_ASSERTION(tag == nsGkAtoms::mover_, "mContent->Tag() not recognized");
|
||||
overscriptFrame = baseFrame->GetNextSibling();
|
||||
}
|
||||
}
|
||||
if (underscriptFrame &&
|
||||
tag == nsGkAtoms::munderover_) {
|
||||
overscriptFrame = underscriptFrame->GetNextSibling();
|
||||
|
||||
}
|
||||
|
||||
// if our base is an embellished operator, let its state bubble to us (in particular,
|
||||
// this is where we get the flag for NS_MATHML_EMBELLISH_MOVABLELIMITS). Our flags
|
||||
// are reset to the default values of false if the base frame isn't embellished.
|
||||
@ -187,39 +219,47 @@ nsMathMLmunderoverFrame::TransmitAutomaticData()
|
||||
// The default value of accentunder is false, unless the underscript is embellished
|
||||
// and its core <mo> is an accent
|
||||
nsEmbellishData embellishData;
|
||||
GetEmbellishDataFrom(underscriptFrame, embellishData);
|
||||
if (NS_MATHML_EMBELLISH_IS_ACCENT(embellishData.flags))
|
||||
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTUNDER;
|
||||
else
|
||||
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTUNDER;
|
||||
|
||||
// if we have an accentunder attribute, it overrides what the underscript said
|
||||
nsAutoString value;
|
||||
if (GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::accentunder_,
|
||||
value)) {
|
||||
if (value.EqualsLiteral("true")) {
|
||||
if (tag == nsGkAtoms::munder_ ||
|
||||
tag == nsGkAtoms::munderover_) {
|
||||
GetEmbellishDataFrom(underscriptFrame, embellishData);
|
||||
if (NS_MATHML_EMBELLISH_IS_ACCENT(embellishData.flags)) {
|
||||
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTUNDER;
|
||||
} else if (value.EqualsLiteral("false")) {
|
||||
} else {
|
||||
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTUNDER;
|
||||
}
|
||||
|
||||
// if we have an accentunder attribute, it overrides what the underscript said
|
||||
if (GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::accentunder_,
|
||||
value)) {
|
||||
if (value.EqualsLiteral("true")) {
|
||||
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTUNDER;
|
||||
} else if (value.EqualsLiteral("false")) {
|
||||
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTUNDER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The default value of accent is false, unless the overscript is embellished
|
||||
// and its core <mo> is an accent
|
||||
GetEmbellishDataFrom(overscriptFrame, embellishData);
|
||||
if (NS_MATHML_EMBELLISH_IS_ACCENT(embellishData.flags))
|
||||
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTOVER;
|
||||
else
|
||||
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTOVER;
|
||||
|
||||
// if we have an accent attribute, it overrides what the overscript said
|
||||
if (GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::accent_,
|
||||
value)) {
|
||||
if (value.EqualsLiteral("true")) {
|
||||
if (tag == nsGkAtoms::mover_ ||
|
||||
tag == nsGkAtoms::munderover_) {
|
||||
GetEmbellishDataFrom(overscriptFrame, embellishData);
|
||||
if (NS_MATHML_EMBELLISH_IS_ACCENT(embellishData.flags)) {
|
||||
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTOVER;
|
||||
} else if (value.EqualsLiteral("false")) {
|
||||
} else {
|
||||
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTOVER;
|
||||
}
|
||||
|
||||
// if we have an accent attribute, it overrides what the overscript said
|
||||
if (GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::accent_,
|
||||
value)) {
|
||||
if (value.EqualsLiteral("true")) {
|
||||
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTOVER;
|
||||
} else if (value.EqualsLiteral("false")) {
|
||||
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTOVER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// disable the stretch-all flag if we are going to act like a superscript
|
||||
@ -243,22 +283,27 @@ nsMathMLmunderoverFrame::TransmitAutomaticData()
|
||||
that math accents and \overline change uncramped styles to their
|
||||
cramped counterparts.
|
||||
*/
|
||||
PRUint32 compress = NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)
|
||||
? NS_MATHML_COMPRESSED : 0;
|
||||
SetIncrementScriptLevel(2, !NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags));
|
||||
PropagatePresentationDataFor(overscriptFrame,
|
||||
~NS_MATHML_DISPLAYSTYLE | compress,
|
||||
NS_MATHML_DISPLAYSTYLE | compress);
|
||||
|
||||
if (tag == nsGkAtoms::mover_ ||
|
||||
tag == nsGkAtoms::munderover_) {
|
||||
PRUint32 compress = NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)
|
||||
? NS_MATHML_COMPRESSED : 0;
|
||||
SetIncrementScriptLevel(tag == nsGkAtoms::mover_ ? 1 : 2,
|
||||
!NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags));
|
||||
PropagatePresentationDataFor(overscriptFrame,
|
||||
~NS_MATHML_DISPLAYSTYLE | compress,
|
||||
NS_MATHML_DISPLAYSTYLE | compress);
|
||||
}
|
||||
/*
|
||||
The TeXBook treats 'under' like a subscript, so p.141 or Rule 13a
|
||||
say it should be compressed
|
||||
*/
|
||||
SetIncrementScriptLevel(1, !NS_MATHML_EMBELLISH_IS_ACCENTUNDER(mEmbellishData.flags));
|
||||
PropagatePresentationDataFor(underscriptFrame,
|
||||
~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED,
|
||||
NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED);
|
||||
|
||||
if (tag == nsGkAtoms::munder_ ||
|
||||
tag == nsGkAtoms::munderover_) {
|
||||
SetIncrementScriptLevel(1, !NS_MATHML_EMBELLISH_IS_ACCENTUNDER(mEmbellishData.flags));
|
||||
PropagatePresentationDataFor(underscriptFrame,
|
||||
~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED,
|
||||
NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -286,15 +331,35 @@ nsMathMLmunderoverFrame::Place(nsRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize)
|
||||
{
|
||||
nsIAtom* tag = mContent->Tag();
|
||||
if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
|
||||
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
|
||||
// place like sub-superscript pair
|
||||
return nsMathMLmsubsupFrame::PlaceSubSupScript(PresContext(),
|
||||
aRenderingContext,
|
||||
aPlaceOrigin,
|
||||
aDesiredSize,
|
||||
this, 0, 0,
|
||||
nsPresContext::CSSPointsToAppUnits(0.5f));
|
||||
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
|
||||
//place like sub sup or subsup
|
||||
nscoord scriptSpace = nsPresContext::CSSPointsToAppUnits(0.5f);
|
||||
if (tag == nsGkAtoms::munderover_) {
|
||||
return nsMathMLmsubsupFrame::PlaceSubSupScript(PresContext(),
|
||||
aRenderingContext,
|
||||
aPlaceOrigin,
|
||||
aDesiredSize,
|
||||
this, 0, 0,
|
||||
scriptSpace);
|
||||
} else if (tag == nsGkAtoms::munder_) {
|
||||
return nsMathMLmsubFrame::PlaceSubScript(PresContext(),
|
||||
aRenderingContext,
|
||||
aPlaceOrigin,
|
||||
aDesiredSize,
|
||||
this, 0,
|
||||
scriptSpace);
|
||||
} else {
|
||||
NS_ASSERTION(tag == nsGkAtoms::mover_, "mContent->Tag() not recognized");
|
||||
return nsMathMLmsupFrame::PlaceSuperScript(PresContext(),
|
||||
aRenderingContext,
|
||||
aPlaceOrigin,
|
||||
aDesiredSize,
|
||||
this, 0,
|
||||
scriptSpace);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
@ -307,17 +372,45 @@ nsMathMLmunderoverFrame::Place(nsRenderingContext& aRenderingContext,
|
||||
nsIFrame* overFrame = nsnull;
|
||||
nsIFrame* underFrame = nsnull;
|
||||
nsIFrame* baseFrame = mFrames.FirstChild();
|
||||
if (baseFrame)
|
||||
underFrame = baseFrame->GetNextSibling();
|
||||
if (underFrame)
|
||||
underSize.ascent = 0;
|
||||
overSize.ascent = 0;
|
||||
if (baseFrame) {
|
||||
if (tag == nsGkAtoms::munder_ ||
|
||||
tag == nsGkAtoms::munderover_) {
|
||||
underFrame = baseFrame->GetNextSibling();
|
||||
} else if (tag == nsGkAtoms::mover_) {
|
||||
overFrame = baseFrame->GetNextSibling();
|
||||
}
|
||||
}
|
||||
if (underFrame && tag == nsGkAtoms::munderover_) {
|
||||
overFrame = underFrame->GetNextSibling();
|
||||
if (!baseFrame || !underFrame || !overFrame || overFrame->GetNextSibling()) {
|
||||
// report an error, encourage people to get their markups in order
|
||||
return ReflowError(aRenderingContext, aDesiredSize);
|
||||
}
|
||||
|
||||
if (tag == nsGkAtoms::munder_) {
|
||||
if (!baseFrame || !underFrame || underFrame->GetNextSibling()) {
|
||||
// report an error, encourage people to get their markups in order
|
||||
return ReflowError(aRenderingContext, aDesiredSize);
|
||||
}
|
||||
}
|
||||
if (tag == nsGkAtoms::mover_) {
|
||||
if (!baseFrame || !overFrame || overFrame->GetNextSibling()) {
|
||||
// report an error, encourage people to get their markups in order
|
||||
return ReflowError(aRenderingContext, aDesiredSize);
|
||||
}
|
||||
}
|
||||
if (tag == nsGkAtoms::munderover_) {
|
||||
if (!baseFrame || !underFrame || !overFrame || overFrame->GetNextSibling()) {
|
||||
// report an error, encourage people to get their markups in order
|
||||
return ReflowError(aRenderingContext, aDesiredSize);
|
||||
}
|
||||
}
|
||||
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
|
||||
GetReflowAndBoundingMetricsFor(underFrame, underSize, bmUnder);
|
||||
GetReflowAndBoundingMetricsFor(overFrame, overSize, bmOver);
|
||||
if (underFrame) {
|
||||
GetReflowAndBoundingMetricsFor(underFrame, underSize, bmUnder);
|
||||
}
|
||||
if (overFrame) {
|
||||
GetReflowAndBoundingMetricsFor(overFrame, overSize, bmOver);
|
||||
}
|
||||
|
||||
nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1);
|
||||
|
||||
@ -387,8 +480,37 @@ nsMathMLmunderoverFrame::Place(nsRenderingContext& aRenderingContext,
|
||||
}
|
||||
else {
|
||||
// Rule 12, App. G, TeXbook
|
||||
// We are going to modify this rule to make it more general.
|
||||
// The idea behind Rule 12 in the TeXBook is to keep the accent
|
||||
// as close to the base as possible, while ensuring that the
|
||||
// distance between the *baseline* of the accent char and
|
||||
// the *baseline* of the base is atleast x-height.
|
||||
// The idea is that for normal use, we would like all the accents
|
||||
// on a line to line up atleast x-height above the baseline
|
||||
// if possible.
|
||||
// When the ascent of the base is >= x-height,
|
||||
// the baseline of the accent char is placed just above the base
|
||||
// (specifically, the baseline of the accent char is placed
|
||||
// above the baseline of the base by the ascent of the base).
|
||||
// For ease of implementation,
|
||||
// this assumes that the font-designer designs accents
|
||||
// in such a way that the bottom of the accent is atleast x-height
|
||||
// above its baseline, otherwise there will be collisions
|
||||
// with the base. Also there should be proper padding between
|
||||
// the bottom of the accent char and its baseline.
|
||||
// The above rule may not be obvious from a first
|
||||
// reading of rule 12 in the TeXBook !!!
|
||||
// The mathml <mover> tag can use accent chars that
|
||||
// do not follow this convention. So we modify TeX's rule
|
||||
// so that TeX's rule gets subsumed for accents that follow
|
||||
// TeX's convention,
|
||||
// while also allowing accents that do not follow the convention :
|
||||
// we try to keep the *bottom* of the accent char atleast x-height
|
||||
// from the baseline of the base char. we also slap on an extra
|
||||
// padding between the accent and base chars.
|
||||
overDelta1 = ruleThickness + onePixel/2;
|
||||
if (bmBase.ascent < xHeight) {
|
||||
if (bmBase.ascent < xHeight) {
|
||||
// also ensure at least x-height above the baseline of the base
|
||||
overDelta1 += xHeight - bmBase.ascent;
|
||||
}
|
||||
overDelta2 = ruleThickness;
|
||||
@ -494,14 +616,21 @@ nsMathMLmunderoverFrame::Place(nsRenderingContext& aRenderingContext,
|
||||
if (aPlaceOrigin) {
|
||||
nscoord dy;
|
||||
// place overscript
|
||||
dy = aDesiredSize.ascent - mBoundingMetrics.ascent + bmOver.ascent - overSize.ascent;
|
||||
FinishReflowChild (overFrame, PresContext(), nsnull, overSize, dxOver, dy, 0);
|
||||
if (overFrame) {
|
||||
dy = aDesiredSize.ascent - mBoundingMetrics.ascent + bmOver.ascent
|
||||
- overSize.ascent;
|
||||
FinishReflowChild (overFrame, PresContext(), nsnull, overSize, dxOver, dy, 0);
|
||||
}
|
||||
// place base
|
||||
dy = aDesiredSize.ascent - baseSize.ascent;
|
||||
FinishReflowChild (baseFrame, PresContext(), nsnull, baseSize, dxBase, dy, 0);
|
||||
// place underscript
|
||||
dy = aDesiredSize.ascent + mBoundingMetrics.descent - bmUnder.descent - underSize.ascent;
|
||||
FinishReflowChild (underFrame, PresContext(), nsnull, underSize, dxUnder, dy, 0);
|
||||
if (underFrame) {
|
||||
dy = aDesiredSize.ascent + mBoundingMetrics.descent - bmUnder.descent
|
||||
- underSize.ascent;
|
||||
FinishReflowChild (underFrame, PresContext(), nsnull, underSize,
|
||||
dxUnder, dy, 0);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user