# HG changeset patch # User Frédéric Wang # Date 1258837865 -3600 # Node ID 505f326e22e8d95b9478a321514996d76dc15297 # Parent 5c05fb5b34fefd0475dab647fa967e62cecdafe6 [mq]: stretch_direction.diff diff --git a/layout/mathml/nsMathMLChar.cpp b/layout/mathml/nsMathMLChar.cpp --- a/layout/mathml/nsMathMLChar.cpp +++ b/layout/mathml/nsMathMLChar.cpp @@ -18,16 +18,17 @@ * 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 * Shyjan Mahamud * Karl Tomlinson , Mozilla Corporation + * Frederic Wang * * 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 @@ -760,21 +761,16 @@ MathFontEnumCallback(const nsString& aFa return PR_TRUE; // don't stop } static nsresult InitGlobals(nsPresContext* aPresContext) { NS_ASSERTION(!gInitialized, "Error -- already initialized"); gInitialized = PR_TRUE; - PRUint32 count = nsMathMLOperators::CountStretchyOperator(); - if (!count) { - // nothing to stretch, so why bother... - return NS_OK; - } // Allocate the placeholders for the preferred parts and variants nsresult rv = NS_ERROR_OUT_OF_MEMORY; gGlyphTableList = new nsGlyphTableList(); if (gGlyphTableList) { rv = gGlyphTableList->Initialize(); } if (NS_FAILED(rv)) { @@ -872,34 +868,33 @@ nsMathMLChar::SetData(nsPresContext* aPr { NS_ASSERTION(!mParent, "invalid call - not allowed for child chars"); if (!gInitialized) { InitGlobals(aPresContext); } mData = aData; // some assumptions until proven otherwise // note that mGlyph is not initialized - mOperator = -1; + mOperator = nsnull; mDirection = NS_STRETCH_DIRECTION_UNSUPPORTED; mBoundingMetrics.Clear(); mGlyphTable = nsnull; // check if stretching is applicable ... if (gGlyphTableList && (1 == mData.Length())) { - mOperator = nsMathMLOperators::FindStretchyOperator(mData[0]); - if (mOperator >= 0) { - mDirection = nsMathMLOperators::GetStretchyDirectionAt(mOperator); + mOperator = nsMathMLOperators::FindOperator(mData[0]); + if (mOperator) { + mDirection = mOperator->GetStretchDirection(); // default tentative table (not the one that is necessarily going to be used) mGlyphTable = gGlyphTableList->GetGlyphTableFor(aPresContext, this); // commom case: we won't bother with the stretching if there is // no glyph table for us... if (!mGlyphTable) { // TODO: consider scaling the base char // never try to stretch this operator again - nsMathMLOperators::DisableStretchyOperatorAt(mOperator); mDirection = NS_STRETCH_DIRECTION_UNSUPPORTED; - mOperator = -1; + mOperator = nsnull; } } } } // ----------------------------------------------------------------------------------- /* The Stretch: @@ -1553,19 +1548,19 @@ nsMathMLChar::StretchInternal(nsPresCont // aStretchHint & NS_STRETCH_MAXWIDTH: float aMaxSize, PRBool aMaxSizeIsAbsolute) { // if we have been called before, and we didn't actually stretch, our // direction may have been set to NS_STRETCH_DIRECTION_UNSUPPORTED. // So first set our direction back to its instrinsic value nsStretchDirection direction = NS_STRETCH_DIRECTION_UNSUPPORTED; - if (mOperator >= 0) { + if (mOperator) { // mOperator is initialized in SetData() and remains unchanged - direction = nsMathMLOperators::GetStretchyDirectionAt(mOperator); + direction = mOperator->GetStretchDirection(); } // Set default font and get the default bounding metrics // mStyleContext is a leaf context used only when stretching happens. // For the base size, the default font should come from the parent context nsFont font = mStyleContext->GetParent()->GetStyleFont()->mFont; // Override with specific fonts if applicable for this character diff --git a/layout/mathml/nsMathMLChar.h b/layout/mathml/nsMathMLChar.h --- a/layout/mathml/nsMathMLChar.h +++ b/layout/mathml/nsMathMLChar.h @@ -18,16 +18,17 @@ * 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 * Shyjan Mahamud * Karl Tomlinson , Mozilla Corporation + * Frederic Wang * * 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 @@ -231,17 +232,17 @@ protected: nsString mData; // support for handling composite stretchy chars like TeX over/under braces nsMathMLChar* mSibling; nsMathMLChar* mParent; private: nsRect mRect; - PRInt32 mOperator; + OperatorData* mOperator; nsStretchDirection mDirection; nsBoundingMetrics mBoundingMetrics; nsStyleContext* mStyleContext; nsGlyphTable* mGlyphTable; nsGlyphCode mGlyph; // mFamily is non-empty when the family for the current size is different // from the family in the nsStyleContext. nsString mFamily; diff --git a/layout/mathml/nsMathMLOperators.cpp b/layout/mathml/nsMathMLOperators.cpp --- a/layout/mathml/nsMathMLOperators.cpp +++ b/layout/mathml/nsMathMLOperators.cpp @@ -45,49 +45,32 @@ #include "nsIComponentManager.h" #include "nsIPersistentProperties2.h" #include "nsNetUtil.h" #include "nsCRT.h" #include "nsMathMLOperators.h" -// operator dictionary entry -struct OperatorData { - OperatorData(void) - : mFlags(0), - mLeftSpace(0.0f), - mRightSpace(0.0f) - { - } - - // member data - nsString mStr; - nsOperatorFlags mFlags; - float mLeftSpace; // unit is em - float mRightSpace; // unit is em -}; - /* The MathML REC says: "If the operator does not occur in the dictionary with the specified form, the renderer should use one of the forms which is available there, in the order of preference: infix, postfix, prefix." The following variable will be used to keep track of all possible forms encountered in the Operator Dictionary. */ static OperatorData* gOperatorFound[4]; static PRInt32 gTableRefCount = 0; -static PRInt32 gOperatorCount = 0; +static PRUint32 gOperatorCount = 0; static OperatorData* gOperatorArray = nsnull; static nsHashtable* gOperatorTable = nsnull; static PRBool gInitialized = PR_FALSE; -static nsTArray* gStretchyOperatorArray = nsnull; static nsTArray* gInvariantCharArray = nsnull; static const PRUnichar kNullCh = PRUnichar('\0'); static const PRUnichar kDashCh = PRUnichar('#'); static const PRUnichar kColonCh = PRUnichar(':'); static const char* const kMathVariant_name[] = { "normal", @@ -108,23 +91,19 @@ static const char* const kMathVariant_na static void SetBooleanProperty(OperatorData* aOperatorData, nsString aName) { if (aName.IsEmpty()) return; - if (aName.EqualsLiteral("stretchy") && (1 == aOperatorData->mStr.Length())) { + if (aName.EqualsLiteral("stretchy") && (1 == aOperatorData->mStr.Length())) aOperatorData->mFlags |= NS_MATHML_OPERATOR_STRETCHY; - if (kNotFound == - nsMathMLOperators::FindStretchyOperator(aOperatorData->mStr[0])) { - gStretchyOperatorArray->AppendElement(aOperatorData); - } - } else if (aName.EqualsLiteral("fence")) + else if (aName.EqualsLiteral("fence")) aOperatorData->mFlags |= NS_MATHML_OPERATOR_FENCE; else if (aName.EqualsLiteral("accent")) aOperatorData->mFlags |= NS_MATHML_OPERATOR_ACCENT; else if (aName.EqualsLiteral("largeop")) aOperatorData->mFlags |= NS_MATHML_OPERATOR_LARGEOP; else if (aName.EqualsLiteral("separator")) aOperatorData->mFlags |= NS_MATHML_OPERATOR_SEPARATOR; else if (aName.EqualsLiteral("movablelimits")) @@ -305,17 +284,17 @@ InitOperators(void) // The first pass is to count the number of operators; the second pass is to // allocate the necessary space for them and to add them in the hash table. for (PRInt32 pass = 1; pass <= 2; pass++) { OperatorData dummyData; OperatorData* operatorData = &dummyData; nsCOMPtr iterator; if (NS_SUCCEEDED(mathfontProp->Enumerate(getter_AddRefs(iterator)))) { PRBool more; - PRInt32 index = 0; + PRUint32 index = 0; nsCAutoString name; nsAutoString attributes; while ((NS_SUCCEEDED(iterator->HasMoreElements(&more))) && more) { nsCOMPtr element; if (NS_SUCCEEDED(iterator->GetNext(getter_AddRefs(element)))) { if (NS_SUCCEEDED(element->GetKey(name)) && NS_SUCCEEDED(element->GetValue(attributes))) { // expected key: operator.\uNNNN.{infix,postfix,prefix} @@ -363,18 +342,17 @@ InitOperators(void) } static nsresult InitGlobals() { gInitialized = PR_TRUE; nsresult rv = NS_ERROR_OUT_OF_MEMORY; gInvariantCharArray = new nsTArray(); - gStretchyOperatorArray = new nsTArray(); - if (gInvariantCharArray && gStretchyOperatorArray) { + if (gInvariantCharArray) { gOperatorTable = new nsHashtable(); if (gOperatorTable) { rv = InitOperators(); } } if (NS_FAILED(rv)) nsMathMLOperators::CleanUp(); return rv; @@ -386,20 +364,16 @@ nsMathMLOperators::CleanUp() if (gInvariantCharArray) { delete gInvariantCharArray; gInvariantCharArray = nsnull; } if (gOperatorArray) { delete[] gOperatorArray; gOperatorArray = nsnull; } - if (gStretchyOperatorArray) { - delete gStretchyOperatorArray; - gStretchyOperatorArray = nsnull; - } if (gOperatorTable) { delete gOperatorTable; gOperatorTable = nsnull; } } void nsMathMLOperators::AddRefTable(void) @@ -545,70 +519,31 @@ nsMathMLOperators::IsMutableOperator(con nsOperatorFlags allFlags = flags[NS_MATHML_OPERATOR_FORM_INFIX] | flags[NS_MATHML_OPERATOR_FORM_POSTFIX] | flags[NS_MATHML_OPERATOR_FORM_PREFIX]; return NS_MATHML_OPERATOR_IS_STRETCHY(allFlags) || NS_MATHML_OPERATOR_IS_LARGEOP(allFlags); } -PRInt32 -nsMathMLOperators::CountStretchyOperator() +OperatorData* +nsMathMLOperators::FindOperator(PRUnichar aOperator) { if (!gInitialized) { InitGlobals(); } - return (gStretchyOperatorArray) ? gStretchyOperatorArray->Length() : 0; -} - -PRInt32 -nsMathMLOperators::FindStretchyOperator(PRUnichar aOperator) -{ - if (!gInitialized) { - InitGlobals(); - } - if (gStretchyOperatorArray) { - for (PRUint32 k = 0; k < gStretchyOperatorArray->Length(); k++) { - OperatorData* data = gStretchyOperatorArray->ElementAt(k); - if (data && (aOperator == data->mStr[0])) { - return k; + if (gOperatorArray) { + for (PRUint32 k = 0; k < gOperatorCount; k++) { + OperatorData* data = gOperatorArray+k; + if (aOperator == data->mStr[0]) { + return data; } } } - return kNotFound; -} - -nsStretchDirection -nsMathMLOperators::GetStretchyDirectionAt(PRInt32 aIndex) -{ - NS_ASSERTION(gStretchyOperatorArray, "invalid call"); - if (gStretchyOperatorArray) { - NS_ASSERTION(aIndex < PRInt32(gStretchyOperatorArray->Length()), - "invalid call"); - OperatorData* data = gStretchyOperatorArray->ElementAt(aIndex); - if (data) { - if (NS_MATHML_OPERATOR_IS_DIRECTION_VERTICAL(data->mFlags)) - return NS_STRETCH_DIRECTION_VERTICAL; - else if (NS_MATHML_OPERATOR_IS_DIRECTION_HORIZONTAL(data->mFlags)) - return NS_STRETCH_DIRECTION_HORIZONTAL; - NS_ASSERTION(PR_FALSE, "*** bad setup ***"); - } - } - return NS_STRETCH_DIRECTION_UNSUPPORTED; -} - -void -nsMathMLOperators::DisableStretchyOperatorAt(PRInt32 aIndex) -{ - NS_ASSERTION(gStretchyOperatorArray, "invalid call"); - if (gStretchyOperatorArray) { - NS_ASSERTION(aIndex < PRInt32(gStretchyOperatorArray->Length()), - "invalid call"); - (*gStretchyOperatorArray)[aIndex] = nsnull; - } + return nsnull; } /* static */ eMATHVARIANT nsMathMLOperators::LookupInvariantChar(const nsAString& aChar) { if (!gInitialized) { InitGlobals(); } diff --git a/layout/mathml/nsMathMLOperators.h b/layout/mathml/nsMathMLOperators.h --- a/layout/mathml/nsMathMLOperators.h +++ b/layout/mathml/nsMathMLOperators.h @@ -105,77 +105,16 @@ enum eMATHVARIANT { eMATHVARIANT_script, eMATHVARIANT_bold_script, eMATHVARIANT_fraktur, eMATHVARIANT_bold_fraktur, eMATHVARIANT_double_struck, eMATHVARIANT_COUNT }; -class nsMathMLOperators { -public: - static void AddRefTable(void); - static void ReleaseTable(void); - static void CleanUp(); - - // LookupOperator: - // Given the string value of an operator and its form (last two bits of flags), - // this method returns true if the operator is found in the Operator Dictionary. - // Attributes of the operator are returned in the output parameters. - // If the operator is not found under the supplied form but is found under a - // different form, the method returns true as well. The caller can test the - // output parameter aFlags to know exactly under which form the operator was - // found in the Operator Dictionary. - static PRBool - LookupOperator(const nsString& aOperator, - const nsOperatorFlags aForm, - nsOperatorFlags* aFlags, - float* aLeftSpace, - float* aRightSpace); - - // LookupOperators: - // Helper to return all the forms under which an operator is listed in the - // Operator Dictionary. The caller must pass arrays of size 4, and use - // aFlags[NS_MATHML_OPERATOR_FORM_{INFIX|POSTFIX|PREFIX}], aLeftSpace[], etc, - // to access the attributes of the operator under a particular form. If the - // operator wasn't found under a form, its entry aFlags[form] is set to zero. - static void - LookupOperators(const nsString& aOperator, - nsOperatorFlags* aFlags, - float* aLeftSpace, - float* aRightSpace); - - // IsMutableOperator: - // Return true if the operator exists and is stretchy or largeop - static PRBool - IsMutableOperator(const nsString& aOperator); - - // Helper functions for stretchy operators. These are used by the - // nsMathMLChar class. - static PRInt32 CountStretchyOperator(); - static PRInt32 FindStretchyOperator(PRUnichar aOperator); - static nsStretchDirection GetStretchyDirectionAt(PRInt32 aIndex); - static void DisableStretchyOperatorAt(PRInt32 aIndex); - - // Return the variant type of one Unicode Mathematical Alphanumeric Symbol - // character (which may be represented by a surrogate pair), or return - // eMATHVARIANT_NONE if aChar is not such a character. - static eMATHVARIANT LookupInvariantChar(const nsAString& aChar); - - // Return the styled Mathematical Alphanumeric Symbol character - // corresponding to a BMP character and a mathvariant value, or return aChar - // if there is no such corresponding character. - // Note the result may be dependent on aChar, and should be considered a - // temporary. - static const nsDependentSubstring - TransformVariantChar(const PRUnichar& aChar, eMATHVARIANT aVariant); -}; - - -//////////////////////////////////////////////////////////////////////////// // Macros that retrieve the bits used to handle operators #define NS_MATHML_OPERATOR_IS_MUTABLE(_flags) \ (NS_MATHML_OPERATOR_MUTABLE == ((_flags) & NS_MATHML_OPERATOR_MUTABLE)) #define NS_MATHML_OPERATOR_HAS_EMBELLISH_ANCESTOR(_flags) \ (NS_MATHML_OPERATOR_EMBELLISH_ANCESTOR == ((_flags) & NS_MATHML_OPERATOR_EMBELLISH_ANCESTOR)) @@ -237,9 +176,90 @@ public: (NS_MATHML_OPERATOR_MAXSIZE_ABSOLUTE == ((_flags) & NS_MATHML_OPERATOR_MAXSIZE_ABSOLUTE)) #define NS_MATHML_OPERATOR_HAS_LEFTSPACE_ATTR(_flags) \ (NS_MATHML_OPERATOR_LEFTSPACE_ATTR == ((_flags) & NS_MATHML_OPERATOR_LEFTSPACE_ATTR)) #define NS_MATHML_OPERATOR_HAS_RIGHTSPACE_ATTR(_flags) \ (NS_MATHML_OPERATOR_RIGHTSPACE_ATTR == ((_flags) & NS_MATHML_OPERATOR_RIGHTSPACE_ATTR)) +// operator dictionary entry +class OperatorData { +public: + OperatorData(void) + : mFlags(0), + mLeftSpace(0.0f), + mRightSpace(0.0f) + { + } + + nsStretchDirection GetStretchDirection() { + if (NS_MATHML_OPERATOR_IS_DIRECTION_VERTICAL(mFlags)) + return NS_STRETCH_DIRECTION_VERTICAL; + else if (NS_MATHML_OPERATOR_IS_DIRECTION_HORIZONTAL(mFlags)) + return NS_STRETCH_DIRECTION_HORIZONTAL; + else + return NS_STRETCH_DIRECTION_UNSUPPORTED; + } + + // member data + nsString mStr; + nsOperatorFlags mFlags; + float mLeftSpace; // unit is em + float mRightSpace; // unit is em +}; + +class nsMathMLOperators { +public: + static void AddRefTable(void); + static void ReleaseTable(void); + static void CleanUp(); + + // LookupOperator: + // Given the string value of an operator and its form (last two bits of flags), + // this method returns true if the operator is found in the Operator Dictionary. + // Attributes of the operator are returned in the output parameters. + // If the operator is not found under the supplied form but is found under a + // different form, the method returns true as well. The caller can test the + // output parameter aFlags to know exactly under which form the operator was + // found in the Operator Dictionary. + static PRBool + LookupOperator(const nsString& aOperator, + const nsOperatorFlags aForm, + nsOperatorFlags* aFlags, + float* aLeftSpace, + float* aRightSpace); + + // LookupOperators: + // Helper to return all the forms under which an operator is listed in the + // Operator Dictionary. The caller must pass arrays of size 4, and use + // aFlags[NS_MATHML_OPERATOR_FORM_{INFIX|POSTFIX|PREFIX}], aLeftSpace[], etc, + // to access the attributes of the operator under a particular form. If the + // operator wasn't found under a form, its entry aFlags[form] is set to zero. + static void + LookupOperators(const nsString& aOperator, + nsOperatorFlags* aFlags, + float* aLeftSpace, + float* aRightSpace); + + // IsMutableOperator: + // Return true if the operator exists and is stretchy or largeop + static PRBool + IsMutableOperator(const nsString& aOperator); + + // Helper function used by the nsMathMLChar class. + static OperatorData* FindOperator(PRUnichar aOperator); + + // Return the variant type of one Unicode Mathematical Alphanumeric Symbol + // character (which may be represented by a surrogate pair), or return + // eMATHVARIANT_NONE if aChar is not such a character. + static eMATHVARIANT LookupInvariantChar(const nsAString& aChar); + + // Return the styled Mathematical Alphanumeric Symbol character + // corresponding to a BMP character and a mathvariant value, or return aChar + // if there is no such corresponding character. + // Note the result may be dependent on aChar, and should be considered a + // temporary. + static const nsDependentSubstring + TransformVariantChar(const PRUnichar& aChar, eMATHVARIANT aVariant); +}; + #endif /* nsMathMLOperators_h___ */