Mirroring of operators for arabic math (Bug 208309) - part 1. r=karlt

This commit is contained in:
Frédéric Wang 2011-12-21 17:22:00 -05:00
Родитель 587545eeb4
Коммит 630d4a18be
9 изменённых файлов: 65 добавлений и 20 удалений

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

@ -1703,7 +1703,8 @@ nsMathMLChar::Stretch(nsPresContext* aPresContext,
nsStretchDirection aStretchDirection,
const nsBoundingMetrics& aContainerSize,
nsBoundingMetrics& aDesiredStretchSize,
PRUint32 aStretchHint)
PRUint32 aStretchHint,
bool aRTL)
{
NS_ASSERTION(!(aStretchHint &
~(NS_STRETCH_VARIABLE_MASK | NS_STRETCH_LARGEOP |
@ -1711,6 +1712,7 @@ nsMathMLChar::Stretch(nsPresContext* aPresContext,
"Unexpected stretch flags");
mDrawNormal = true;
mMirrored = aRTL && nsMathMLOperators::IsMirrorableOperator(mData);
mScaleY = mScaleX = 1.0;
mDirection = aStretchDirection;
nsresult rv =
@ -1796,10 +1798,11 @@ nsMathMLChar::ComposeChildren(nsPresContext* aPresContext,
child->mDirection = mDirection;
child->mStyleContext = mStyleContext;
child->mGlyphTable = aGlyphTable; // the child is associated to this table
child->mMirrored = mMirrored;
// there goes the Stretch() ...
nsBoundingMetrics childSize;
nsresult rv = child->Stretch(aPresContext, aRenderingContext, mDirection,
splitSize, childSize, aStretchHint);
splitSize, childSize, aStretchHint, mMirrored);
// check if something went wrong or the child couldn't fit in the alloted space
if (NS_FAILED(rv) || (NS_STRETCH_DIRECTION_UNSUPPORTED == child->mDirection)) {
delete mSibling; // don't leave a dangling list behind ...
@ -2028,8 +2031,13 @@ void
nsMathMLChar::ApplyTransforms(nsRenderingContext& aRenderingContext, nsRect &r)
{
// apply the transforms
aRenderingContext.Translate(r.TopLeft());
aRenderingContext.Scale(mScaleX, mScaleY);
if (mMirrored) {
aRenderingContext.Translate(r.TopRight());
aRenderingContext.Scale(-mScaleX, mScaleY);
} else {
aRenderingContext.Translate(r.TopLeft());
aRenderingContext.Scale(mScaleX, mScaleY);
}
// update the bounding rectangle.
r.x = r.y = 0;

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

@ -112,6 +112,7 @@ public:
mUnscaledAscent = 0;
mScaleX = mScaleY = 1.0;
mDrawNormal = true;
mMirrored = false;
}
~nsMathMLChar() { // not a virtual destructor: this class is not intended to be subclassed
@ -146,7 +147,8 @@ public:
nsStretchDirection aStretchDirection,
const nsBoundingMetrics& aContainerSize,
nsBoundingMetrics& aDesiredStretchSize,
PRUint32 aStretchHint = NS_STRETCH_NORMAL);
PRUint32 aStretchHint,
bool aRTL);
void
SetData(nsPresContext* aPresContext,
@ -258,6 +260,8 @@ private:
float mScaleX, mScaleY;
// mDrawNormal indicates whether we use special glyphs or not.
bool mDrawNormal;
// mMirrored indicates whether the character is mirrored.
bool mMirrored;
class StretchEnumContext;
friend class StretchEnumContext;

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

@ -117,6 +117,8 @@ SetBooleanProperty(OperatorData* aOperatorData,
aOperatorData->mFlags |= NS_MATHML_OPERATOR_SYMMETRIC;
else if (aName.EqualsLiteral("integral"))
aOperatorData->mFlags |= NS_MATHML_OPERATOR_INTEGRAL;
else if (aName.EqualsLiteral("mirrorable"))
aOperatorData->mFlags |= NS_MATHML_OPERATOR_MIRRORABLE;
}
static void
@ -515,6 +517,20 @@ nsMathMLOperators::IsMutableOperator(const nsString& aOperator)
NS_MATHML_OPERATOR_IS_LARGEOP(allFlags);
}
/* static */ bool
nsMathMLOperators::IsMirrorableOperator(const nsString& aOperator)
{
// LookupOperator will search infix, postfix and prefix forms of aOperator and
// return the first form found. It is assumed that all these forms have same
// mirrorability.
nsOperatorFlags flags = 0;
float dummy;
nsMathMLOperators::LookupOperator(aOperator,
NS_MATHML_OPERATOR_FORM_INFIX,
&flags, &dummy, &dummy);
return NS_MATHML_OPERATOR_IS_MIRRORABLE(flags);
}
/* static */ nsStretchDirection
nsMathMLOperators::GetStretchyDirection(const nsString& aOperator)
{

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

@ -81,12 +81,13 @@ enum {
NS_MATHML_OPERATOR_MOVABLELIMITS = 1<<9,
NS_MATHML_OPERATOR_SYMMETRIC = 1<<10,
NS_MATHML_OPERATOR_INTEGRAL = 1<<11,
NS_MATHML_OPERATOR_MIRRORABLE = 1<<12,
// Additional bits not stored in the dictionary
NS_MATHML_OPERATOR_MINSIZE_ABSOLUTE = 1<<12,
NS_MATHML_OPERATOR_MAXSIZE_ABSOLUTE = 1<<13,
NS_MATHML_OPERATOR_LSPACE_ATTR = 1<<14,
NS_MATHML_OPERATOR_RSPACE_ATTR = 1<<15
NS_MATHML_OPERATOR_MINSIZE_ABSOLUTE = 1<<13,
NS_MATHML_OPERATOR_MAXSIZE_ABSOLUTE = 1<<14,
NS_MATHML_OPERATOR_LSPACE_ATTR = 1<<15,
NS_MATHML_OPERATOR_RSPACE_ATTR = 1<<16
};
#define NS_MATHML_OPERATOR_SIZE_INFINITY NS_IEEEPositiveInfinity()
@ -150,6 +151,10 @@ public:
static bool
IsMutableOperator(const nsString& aOperator);
// Helper functions used by the nsMathMLChar class.
static bool
IsMirrorableOperator(const nsString& aOperator);
// Helper function used by the nsMathMLChar class.
static nsStretchDirection GetStretchyDirection(const nsString& aOperator);
@ -230,6 +235,9 @@ public:
#define NS_MATHML_OPERATOR_IS_INTEGRAL(_flags) \
(NS_MATHML_OPERATOR_INTEGRAL == ((_flags) & NS_MATHML_OPERATOR_INTEGRAL))
#define NS_MATHML_OPERATOR_IS_MIRRORABLE(_flags) \
(NS_MATHML_OPERATOR_MIRRORABLE == ((_flags) & NS_MATHML_OPERATOR_MIRRORABLE))
#define NS_MATHML_OPERATOR_MINSIZE_IS_ABSOLUTE(_flags) \
(NS_MATHML_OPERATOR_MINSIZE_ABSOLUTE == ((_flags) & NS_MATHML_OPERATOR_MINSIZE_ABSOLUTE))

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

@ -497,7 +497,7 @@ nsMathMLmencloseFrame::PlaceInternal(nsRenderingContext& aRenderingContext,
mMathMLChar[mLongDivCharIndex].Stretch(PresContext(), aRenderingContext,
NS_STRETCH_DIRECTION_VERTICAL,
contSize, bmLongdivChar,
NS_STRETCH_LARGER);
NS_STRETCH_LARGER, false);
mMathMLChar[mLongDivCharIndex].GetBoundingMetrics(bmLongdivChar);
// Update horizontal parameters
@ -539,7 +539,8 @@ nsMathMLmencloseFrame::PlaceInternal(nsRenderingContext& aRenderingContext,
mMathMLChar[mRadicalCharIndex].Stretch(PresContext(), aRenderingContext,
NS_STRETCH_DIRECTION_VERTICAL,
contSize, bmRadicalChar,
NS_STRETCH_LARGER);
NS_STRETCH_LARGER,
NS_MATHML_IS_RTL(mPresentationData.flags));
mMathMLChar[mRadicalCharIndex].GetBoundingMetrics(bmRadicalChar);
// Update horizontal parameters

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

@ -357,23 +357,25 @@ nsMathMLmfencedFrame::Reflow(nsPresContext* aPresContext,
containerSize.ascent = delta + axisHeight;
containerSize.descent = delta - axisHeight;
bool isRTL = NS_MATHML_IS_RTL(mPresentationData.flags);
/////////////////
// opening fence ...
ReflowChar(aPresContext, *aReflowState.rendContext, mOpenChar,
NS_MATHML_OPERATOR_FORM_PREFIX, font->mScriptLevel,
axisHeight, leading, em, containerSize, ascent, descent);
axisHeight, leading, em, containerSize, ascent, descent, isRTL);
/////////////////
// separators ...
for (i = 0; i < mSeparatorsCount; i++) {
ReflowChar(aPresContext, *aReflowState.rendContext, &mSeparatorsChar[i],
NS_MATHML_OPERATOR_FORM_INFIX, font->mScriptLevel,
axisHeight, leading, em, containerSize, ascent, descent);
axisHeight, leading, em, containerSize, ascent, descent, isRTL);
}
/////////////////
// closing fence ...
ReflowChar(aPresContext, *aReflowState.rendContext, mCloseChar,
NS_MATHML_OPERATOR_FORM_POSTFIX, font->mScriptLevel,
axisHeight, leading, em, containerSize, ascent, descent);
axisHeight, leading, em, containerSize, ascent, descent, isRTL);
//////////////////
// Adjust the origins of each child.
@ -384,7 +386,6 @@ nsMathMLmfencedFrame::Reflow(nsPresContext* aPresContext,
nsBoundingMetrics bm;
bool firstTime = true;
nsMathMLChar *leftChar, *rightChar;
bool isRTL = NS_MATHML_IS_RTL(mPresentationData.flags);
if (isRTL) {
leftChar = mCloseChar;
rightChar = mOpenChar;
@ -499,7 +500,8 @@ nsMathMLmfencedFrame::ReflowChar(nsPresContext* aPresContext,
nscoord em,
nsBoundingMetrics& aContainerSize,
nscoord& aAscent,
nscoord& aDescent)
nscoord& aDescent,
bool aRTL)
{
if (aMathMLChar && 0 < aMathMLChar->Length()) {
nscoord leftSpace;
@ -510,7 +512,8 @@ nsMathMLmfencedFrame::ReflowChar(nsPresContext* aPresContext,
nsBoundingMetrics charSize;
nsresult res = aMathMLChar->Stretch(aPresContext, aRenderingContext,
NS_STRETCH_DIRECTION_VERTICAL,
aContainerSize, charSize);
aContainerSize, charSize,
NS_STRETCH_NORMAL, aRTL);
if (NS_STRETCH_DIRECTION_UNSUPPORTED != aMathMLChar->GetStretchDirection()) {
// has changed... so center the char around the axis

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

@ -105,7 +105,8 @@ public:
nscoord em,
nsBoundingMetrics& aContainerSize,
nscoord& aAscent,
nscoord& aDescent);
nscoord& aDescent,
bool aRTL);
static void
PlaceChar(nsMathMLChar* aMathMLChar,

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

@ -760,7 +760,10 @@ nsMathMLmoFrame::Stretch(nsRenderingContext& aRenderingContext,
// let the MathMLChar stretch itself...
nsresult res = mMathMLChar.Stretch(PresContext(), aRenderingContext,
aStretchDirection, container, charSize, stretchHint);
aStretchDirection, container, charSize,
stretchHint,
NS_MATHML_IS_RTL(mPresentationData.
flags));
if (NS_FAILED(res)) {
// 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

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

@ -311,7 +311,8 @@ nsMathMLmrootFrame::Reflow(nsPresContext* aPresContext,
mSqrChar.Stretch(aPresContext, renderingContext,
NS_STRETCH_DIRECTION_VERTICAL,
contSize, radicalSize,
NS_STRETCH_LARGER);
NS_STRETCH_LARGER,
NS_MATHML_IS_RTL(mPresentationData.flags));
// radicalSize have changed at this point, and should match with
// the bounding metrics of the char
mSqrChar.GetBoundingMetrics(bmSqr);