Back to index

lightning-sunbird  0.9+nobinonly
nsMathMLmstyleFrame.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is Mozilla MathML Project.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * The University Of Queensland.
00018  * Portions created by the Initial Developer are Copyright (C) 1999
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *   Roger B. Sidje <rbs@maths.uq.edu.au>
00023  *   David J. Fiddes <D.J.Fiddes@hw.ac.uk>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 
00040 #include "nsCOMPtr.h"
00041 #include "nsFrame.h"
00042 #include "nsPresContext.h"
00043 #include "nsUnitConversion.h"
00044 #include "nsStyleContext.h"
00045 #include "nsStyleConsts.h"
00046 #include "nsINameSpaceManager.h"
00047 #include "nsIRenderingContext.h"
00048 #include "nsIFontMetrics.h"
00049 
00050 #include "nsMathMLmstyleFrame.h"
00051 
00052 //
00053 // <mstyle> -- style change
00054 //
00055 
00056 nsresult
00057 NS_NewMathMLmstyleFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
00058 {
00059   NS_PRECONDITION(aNewFrame, "null OUT ptr");
00060   if (nsnull == aNewFrame) {
00061     return NS_ERROR_NULL_POINTER;
00062   }
00063   nsMathMLmstyleFrame* it = new (aPresShell) nsMathMLmstyleFrame;
00064   if (nsnull == it) {
00065     return NS_ERROR_OUT_OF_MEMORY;
00066   }
00067   *aNewFrame = it;  
00068   return NS_OK;
00069 }
00070 
00071 nsMathMLmstyleFrame::nsMathMLmstyleFrame()
00072 {
00073 }
00074 
00075 nsMathMLmstyleFrame::~nsMathMLmstyleFrame()
00076 {
00077 }
00078 
00079 // mstyle needs special care for its scriptlevel and displaystyle attributes
00080 NS_IMETHODIMP
00081 nsMathMLmstyleFrame::InheritAutomaticData(nsIFrame* aParent) 
00082 {
00083   // let the base class get the default from our parent
00084   nsMathMLContainerFrame::InheritAutomaticData(aParent);
00085 
00086   // sync with our current state
00087   mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
00088   mPresentationData.mstyle = this;
00089 
00090   // see if the displaystyle attribute is there
00091   nsAutoString value;
00092   if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttr(kNameSpaceID_None, 
00093                    nsMathMLAtoms::displaystyle_, value)) {
00094     if (value.EqualsLiteral("true")) {
00095       mPresentationData.flags |= NS_MATHML_MSTYLE_WITH_DISPLAYSTYLE;
00096       mPresentationData.flags |= NS_MATHML_DISPLAYSTYLE;
00097     }
00098     else if (value.EqualsLiteral("false")) {
00099       mPresentationData.flags |= NS_MATHML_MSTYLE_WITH_DISPLAYSTYLE;
00100       mPresentationData.flags &= ~NS_MATHML_DISPLAYSTYLE;
00101     }
00102   }
00103 
00104   // see if the scriptlevel attribute is there
00105   if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttr(kNameSpaceID_None, 
00106                    nsMathMLAtoms::scriptlevel_, value)) {
00107     PRInt32 errorCode, userValue;
00108     userValue = value.ToInteger(&errorCode); 
00109     if (!errorCode) {
00110       if (value[0] != '+' && value[0] != '-') { // record that it is an explicit value
00111         mPresentationData.flags |= NS_MATHML_MSTYLE_WITH_EXPLICIT_SCRIPTLEVEL;
00112         mPresentationData.scriptLevel = userValue;
00113       }
00114       else {
00115         mPresentationData.scriptLevel += userValue; // incremental value...
00116       }
00117     }
00118   }
00119 
00120   return NS_OK;
00121 }
00122 
00123 NS_IMETHODIMP
00124 nsMathMLmstyleFrame::TransmitAutomaticData()
00125 {
00126   // Nothing particular to do here, the values that we computed in
00127   // InheritAutomaticData() are the values that we wanted to pass to
00128   // our children. Our children would have inherited these values in
00129   // their own InheritAutomaticData() as we descended the frame tree.
00130 
00131   return NS_OK;
00132 }
00133 
00134 NS_IMETHODIMP
00135 nsMathMLmstyleFrame::UpdatePresentationData(PRInt32         aScriptLevelIncrement,
00136                                             PRUint32        aFlagsValues,
00137                                             PRUint32        aFlagsToUpdate)
00138 {
00139   // mstyle is special...
00140   // Since UpdatePresentationData() can be called by a parent frame, the
00141   // scriptlevel and displaystyle attributes of mstyle must take precedence.
00142   // Update only if attributes are not there
00143 
00144   // see if updating the displaystyle flag is allowed
00145   if (!NS_MATHML_IS_MSTYLE_WITH_DISPLAYSTYLE(mPresentationData.flags)) {
00146     // see if the displaystyle flag is relevant to this call
00147     if (NS_MATHML_IS_DISPLAYSTYLE(aFlagsToUpdate)) {
00148       if (NS_MATHML_IS_DISPLAYSTYLE(aFlagsValues)) {
00149         mPresentationData.flags |= NS_MATHML_DISPLAYSTYLE;
00150       }
00151       else {
00152         mPresentationData.flags &= ~NS_MATHML_DISPLAYSTYLE;
00153       }
00154     }
00155   }
00156 
00157   // see if updating the scriptlevel is allowed
00158   if (!NS_MATHML_IS_MSTYLE_WITH_EXPLICIT_SCRIPTLEVEL(mPresentationData.flags)) {
00159     mPresentationData.scriptLevel += aScriptLevelIncrement;
00160   }
00161 
00162   // see if the compression flag is relevant to this call
00163   if (NS_MATHML_IS_COMPRESSED(aFlagsToUpdate)) {
00164     if (NS_MATHML_IS_COMPRESSED(aFlagsValues)) {
00165       // 'compressed' means 'prime' style in App. G, TeXbook
00166       mPresentationData.flags |= NS_MATHML_COMPRESSED;
00167     }
00168     // no else. the flag is sticky. it retains its value once it is set
00169   }
00170 
00171   return NS_OK;
00172 }
00173 
00174 NS_IMETHODIMP
00175 nsMathMLmstyleFrame::UpdatePresentationDataFromChildAt(PRInt32         aFirstIndex,
00176                                                        PRInt32         aLastIndex,
00177                                                        PRInt32         aScriptLevelIncrement,
00178                                                        PRUint32        aFlagsValues,
00179                                                        PRUint32        aFlagsToUpdate)
00180 {
00181   // mstyle is special...
00182   // Since UpdatePresentationDataFromChildAt() can be called by a parent frame,
00183   // wee need to ensure that the attributes of mstyle take precedence
00184 
00185   if (NS_MATHML_IS_DISPLAYSTYLE(aFlagsToUpdate)) {
00186     if (NS_MATHML_IS_MSTYLE_WITH_DISPLAYSTYLE(mPresentationData.flags)) {
00187       // our current state takes precedence, updating is not allowed
00188       aFlagsToUpdate &= ~NS_MATHML_DISPLAYSTYLE;
00189       aFlagsValues &= ~NS_MATHML_DISPLAYSTYLE;
00190     }
00191   }
00192 
00193   if (NS_MATHML_IS_MSTYLE_WITH_EXPLICIT_SCRIPTLEVEL(mPresentationData.flags)) {
00194     // our current state takes precedence, updating is not allowed
00195     aScriptLevelIncrement = 0;
00196   }
00197 
00198   // let the base class worry about the update
00199   return
00200     nsMathMLContainerFrame::UpdatePresentationDataFromChildAt(
00201       aFirstIndex, aLastIndex, aScriptLevelIncrement,
00202       aFlagsValues, aFlagsToUpdate); 
00203 }
00204 
00205 NS_IMETHODIMP
00206 nsMathMLmstyleFrame::AttributeChanged(nsIContent*     aContent,
00207                                       PRInt32         aNameSpaceID,
00208                                       nsIAtom*        aAttribute,
00209                                       PRInt32         aModType)
00210 {
00211   if (aAttribute == nsMathMLAtoms::mathcolor_      ||
00212       aAttribute == nsMathMLAtoms::color_          ||
00213       aAttribute == nsMathMLAtoms::mathsize_       ||
00214       aAttribute == nsMathMLAtoms::fontsize_       ||
00215       aAttribute == nsMathMLAtoms::fontfamily_     ||
00216       aAttribute == nsMathMLAtoms::mathbackground_ ||
00217       aAttribute == nsMathMLAtoms::background_) {
00218     MapAttributesIntoCSS(GetPresContext(), this);
00219     return ReflowDirtyChild(GetPresContext()->PresShell(), nsnull);
00220   }
00221 
00222   // Other attributes can affect too many things, ask our parent to re-layout
00223   // its children so that we can pick up changes in our attributes & transmit
00224   // them in our subtree. However, our siblings will be re-laid too. We used
00225   // to have a more speedier but more verbose alternative that didn't re-layout
00226   // our siblings. See bug 114909 - attachment 67668.
00227   return ReLayoutChildren(mParent);
00228 }