nsresult nsMathMLmencloseFrame::AllocateMathMLChar(nsMencloseNotation mask) { // Is the char already allocated? if ((mask == NOTATION_LONGDIV && mLongDivCharIndex >= 0) || (mask == NOTATION_RADICAL && mRadicalCharIndex >= 0)) return NS_OK; // No need to track the style context given to our MathML chars. // The Style System will use Get/SetAdditionalStyleContext() to keep it // up-to-date if dynamic changes arise. PRUint32 i = mMathMLChar.Length(); nsAutoString Char; if (!mMathMLChar.AppendElement()) return NS_ERROR_OUT_OF_MEMORY; if (mask == NOTATION_LONGDIV) { Char.Assign(kLongDivChar); mLongDivCharIndex = i; } else if (mask == NOTATION_RADICAL) { Char.Assign(kRadicalChar); mRadicalCharIndex = i; } nsPresContext *presContext = PresContext(); mMathMLChar[i].SetData(presContext, Char); ResolveMathMLCharStyle(presContext, mContent, mStyleContext, &mMathMLChar[i], true); return NS_OK; }
NS_IMETHODIMP nsMathMLmfracFrame::AttributeChanged(PRInt32 aNameSpaceID, nsIAtom* aAttribute, PRInt32 aModType) { if (nsGkAtoms::bevelled_ == aAttribute) { if (!IsBevelled()) { // disable the bevelled rendering if (mSlashChar) { delete mSlashChar; mSlashChar = nsnull; } } else { // enable the bevelled rendering if (!mSlashChar) { mSlashChar = new nsMathMLChar(); if (mSlashChar) { nsPresContext* presContext = PresContext(); nsAutoString slashChar; slashChar.Assign(kSlashChar); mSlashChar->SetData(presContext, slashChar); ResolveMathMLCharStyle(presContext, mContent, mStyleContext, mSlashChar, PR_TRUE); } } } } return nsMathMLContainerFrame:: AttributeChanged(aNameSpaceID, aAttribute, aModType); }
void nsMathMLmrootFrame::Init(nsIContent* aContent, nsIFrame* aParent, nsIFrame* aPrevInFlow) { nsMathMLContainerFrame::Init(aContent, aParent, aPrevInFlow); nsPresContext *presContext = PresContext(); // No need to track the style context given to our MathML char. // The Style System will use Get/SetAdditionalStyleContext() to keep it // up-to-date if dynamic changes arise. nsAutoString sqrChar; sqrChar.Assign(kSqrChar); mSqrChar.SetData(presContext, sqrChar); ResolveMathMLCharStyle(presContext, mContent, mStyleContext, &mSqrChar, true); }
NS_IMETHODIMP nsMathMLmsqrtFrame::Init(nsPresContext* aPresContext, nsIContent* aContent, nsIFrame* aParent, nsStyleContext* aContext, nsIFrame* aPrevInFlow) { nsresult rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow); // No need to tract the style context given to our MathML char. // The Style System will use Get/SetAdditionalStyleContext() to keep it // up-to-date if dynamic changes arise. nsAutoString sqrChar; sqrChar.Assign(kSqrChar); mSqrChar.SetData(aPresContext, sqrChar); ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, &mSqrChar, PR_TRUE); return rv; }
NS_IMETHODIMP nsMathMLmfracFrame::Init(nsIContent* aContent, nsIFrame* aParent, nsIFrame* aPrevInFlow) { nsresult rv = nsMathMLContainerFrame::Init(aContent, aParent, aPrevInFlow); if (IsBevelled()) { // enable the bevelled rendering mSlashChar = new nsMathMLChar(); if (mSlashChar) { nsPresContext* presContext = PresContext(); nsAutoString slashChar; slashChar.Assign(kSlashChar); mSlashChar->SetData(presContext, slashChar); ResolveMathMLCharStyle(presContext, mContent, mStyleContext, mSlashChar, PR_TRUE); } } return rv; }
void nsMathMLmfencedFrame::CreateFencesAndSeparators(nsPresContext* aPresContext) { nsAutoString value; PRBool isMutable = PR_FALSE; ////////////// // see if the opening fence is there ... if (!GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::open, value)) { value = PRUnichar('('); // default as per the MathML REC } else { value.CompressWhitespace(); } if (!value.IsEmpty()) { mOpenChar = new nsMathMLChar; mOpenChar->SetData(aPresContext, value); isMutable = nsMathMLOperators::IsMutableOperator(value); ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, mOpenChar, isMutable); } ////////////// // see if the closing fence is there ... if(!GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::close, value)) { value = PRUnichar(')'); // default as per the MathML REC } else { value.CompressWhitespace(); } if (!value.IsEmpty()) { mCloseChar = new nsMathMLChar; mCloseChar->SetData(aPresContext, value); isMutable = nsMathMLOperators::IsMutableOperator(value); ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, mCloseChar, isMutable); } ////////////// // see if separators are there ... if (!GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::separators_, value)) { value = PRUnichar(','); // default as per the MathML REC } else { value.StripWhitespace(); } mSeparatorsCount = value.Length(); if (0 < mSeparatorsCount) { PRInt32 sepCount = mFrames.GetLength() - 1; if (0 < sepCount) { mSeparatorsChar = new nsMathMLChar[sepCount]; nsAutoString sepChar; for (PRInt32 i = 0; i < sepCount; i++) { if (i < mSeparatorsCount) { sepChar = value[i]; isMutable = nsMathMLOperators::IsMutableOperator(sepChar); } else { sepChar = value[mSeparatorsCount-1]; // keep the value of isMutable that was set earlier } mSeparatorsChar[i].SetData(aPresContext, sepChar); ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, &mSeparatorsChar[i], isMutable); } mSeparatorsCount = sepCount; } else { // No separators. Note that sepCount can be -1 here, so don't // set mSeparatorsCount to it. mSeparatorsCount = 0; } } }
// get the text that we enclose and setup our nsMathMLChar void nsMathMLmoFrame::ProcessTextData() { mFlags = 0; nsAutoString data; nsContentUtils::GetNodeTextContent(mContent, false, data); data.CompressWhitespace(); int32_t length = data.Length(); PRUnichar ch = (length == 0) ? kNullCh : data[0]; if ((length == 1) && (ch == kInvisibleComma || ch == kApplyFunction || ch == kInvisibleTimes)) { mFlags |= NS_MATHML_OPERATOR_INVISIBLE; } // don't bother doing anything special if we don't have a // single child with a visible text content nsPresContext* presContext = PresContext(); if (NS_MATHML_OPERATOR_IS_INVISIBLE(mFlags) || mFrames.GetLength() != 1) { data.Truncate(); // empty data to reset the char mMathMLChar.SetData(presContext, data); ResolveMathMLCharStyle(presContext, mContent, mStyleContext, &mMathMLChar, false); return; } // special... in math mode, the usual minus sign '-' looks too short, so // what we do here is to remap <mo>-</mo> to the official Unicode minus // sign (U+2212) which looks much better. For background on this, see // http://groups.google.com/groups?hl=en&th=66488daf1ade7635&rnum=1 if (1 == length && ch == '-') { ch = 0x2212; data = ch; } // cache the special bits: mutable, accent, movablelimits, centered. // we need to do this in anticipation of other requirements, and these // bits don't change. Do not reset these bits unless the text gets changed. // lookup all the forms under which the operator is listed in the dictionary, // and record whether the operator has accent="true" or movablelimits="true" nsOperatorFlags flags[4]; float lspace[4], rspace[4]; nsMathMLOperators::LookupOperators(data, flags, lspace, rspace); nsOperatorFlags allFlags = flags[NS_MATHML_OPERATOR_FORM_INFIX] | flags[NS_MATHML_OPERATOR_FORM_POSTFIX] | flags[NS_MATHML_OPERATOR_FORM_PREFIX]; mFlags |= allFlags & NS_MATHML_OPERATOR_ACCENT; mFlags |= allFlags & NS_MATHML_OPERATOR_MOVABLELIMITS; bool isMutable = NS_MATHML_OPERATOR_IS_STRETCHY(allFlags) || NS_MATHML_OPERATOR_IS_LARGEOP(allFlags); if (isMutable) mFlags |= NS_MATHML_OPERATOR_MUTABLE; // see if this is an operator that should be centered to cater for // fonts that are not math-aware if (1 == length) { if ((ch == '+') || (ch == '=') || (ch == '*') || (ch == 0x2212) || // − (ch == 0x2264) || // ≤ (ch == 0x2265) || // ≥ (ch == 0x00D7)) { // × mFlags |= NS_MATHML_OPERATOR_CENTERED; } } // cache the operator mMathMLChar.SetData(presContext, data); ResolveMathMLCharStyle(presContext, mContent, mStyleContext, &mMathMLChar, isMutable); // cache the native direction -- beware of bug 133429... // mEmbellishData.direction must always retain our native direction, whereas // mMathMLChar.GetStretchDirection() may change later, when Stretch() is called mEmbellishData.direction = mMathMLChar.GetStretchDirection(); }
void nsMathMLmfencedFrame::CreateFencesAndSeparators(nsPresContext* aPresContext) { nsAutoString value; ////////////// // see if the opening fence is there ... if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::open, value)) { value = char16_t('('); // default as per the MathML REC } else { value.CompressWhitespace(); } if (!value.IsEmpty()) { mOpenChar = new nsMathMLChar; mOpenChar->SetData(aPresContext, value); ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, mOpenChar); } ////////////// // see if the closing fence is there ... if(!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::close, value)) { value = char16_t(')'); // default as per the MathML REC } else { value.CompressWhitespace(); } if (!value.IsEmpty()) { mCloseChar = new nsMathMLChar; mCloseChar->SetData(aPresContext, value); ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, mCloseChar); } ////////////// // see if separators are there ... if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::separators_, value)) { value = char16_t(','); // default as per the MathML REC } else { value.StripWhitespace(); } mSeparatorsCount = value.Length(); if (0 < mSeparatorsCount) { int32_t sepCount = mFrames.GetLength() - 1; if (0 < sepCount) { mSeparatorsChar = new nsMathMLChar[sepCount]; nsAutoString sepChar; for (int32_t i = 0; i < sepCount; i++) { if (i < mSeparatorsCount) { sepChar = value[i]; } else { sepChar = value[mSeparatorsCount-1]; } mSeparatorsChar[i].SetData(aPresContext, sepChar); ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, &mSeparatorsChar[i]); } mSeparatorsCount = sepCount; } else { // No separators. Note that sepCount can be -1 here, so don't // set mSeparatorsCount to it. mSeparatorsCount = 0; } } }