Back to index

lightning-sunbird  0.9+nobinonly
nsMathMLFrame.h
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  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #ifndef nsMathMLFrame_h___
00039 #define nsMathMLFrame_h___
00040 
00041 #include "nsCOMPtr.h"
00042 #include "nsPresContext.h"
00043 #include "nsIRenderingContext.h"
00044 #include "nsIFontMetrics.h"
00045 #include "nsStyleContext.h"
00046 #include "nsMathMLAtoms.h"
00047 #include "nsMathMLOperators.h"
00048 #include "nsIMathMLFrame.h"
00049 #include "nsFrame.h"
00050 #include "nsCSSValue.h"
00051 
00052 class nsMathMLChar;
00053 
00054 // Concrete base class with default methods that derived MathML frames can override
00055 class nsMathMLFrame : public nsIMathMLFrame {
00056 public:
00057 
00058   // nsISupports ------
00059 
00060   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
00061 
00062   NS_IMETHOD_(nsrefcnt) AddRef() {
00063     // not meaningfull for frames
00064     return 1;
00065   }
00066 
00067   NS_IMETHOD_(nsrefcnt) Release() {
00068     // not meaningfull for frames
00069     return 1;
00070   }
00071 
00072   // nsIMathMLFrame ---
00073 
00074   NS_IMETHOD
00075   GetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics) {
00076     aBoundingMetrics = mBoundingMetrics;
00077     return NS_OK;
00078   }
00079 
00080   NS_IMETHOD
00081   SetBoundingMetrics(const nsBoundingMetrics& aBoundingMetrics) {
00082     mBoundingMetrics = aBoundingMetrics;
00083     return NS_OK;
00084   }
00085 
00086   NS_IMETHOD
00087   GetReference(nsPoint& aReference) {
00088     aReference = mReference;
00089     return NS_OK;
00090   }
00091 
00092   NS_IMETHOD
00093   SetReference(const nsPoint& aReference) {
00094     mReference = aReference;
00095     return NS_OK;
00096   }
00097 
00098   virtual eMathMLFrameType GetMathMLFrameType();
00099 
00100   NS_IMETHOD
00101   Stretch(nsIRenderingContext& aRenderingContext,
00102           nsStretchDirection   aStretchDirection,
00103           nsBoundingMetrics&   aContainerSize,
00104           nsHTMLReflowMetrics& aDesiredStretchSize)
00105   {
00106     return NS_OK;
00107   }
00108 
00109   NS_IMETHOD
00110   Place(nsIRenderingContext& aRenderingContext,
00111         PRBool               aPlaceOrigin,
00112         nsHTMLReflowMetrics& aDesiredSize)
00113   {
00114     return NS_OK;
00115   }
00116 
00117   NS_IMETHOD
00118   GetEmbellishData(nsEmbellishData& aEmbellishData) {
00119     aEmbellishData = mEmbellishData;
00120     return NS_OK;
00121   }
00122  
00123   NS_IMETHOD
00124   SetEmbellishData(const nsEmbellishData& aEmbellishData) {
00125     mEmbellishData = aEmbellishData;
00126     return NS_OK;
00127   }
00128 
00129   NS_IMETHOD
00130   GetPresentationData(nsPresentationData& aPresentationData) {
00131     aPresentationData = mPresentationData;
00132     return NS_OK;
00133   }
00134 
00135   NS_IMETHOD
00136   SetPresentationData(const nsPresentationData& aPresentationData) {
00137     mPresentationData = aPresentationData;
00138     return NS_OK;
00139   }
00140 
00141   NS_IMETHOD
00142   InheritAutomaticData(nsIFrame* aParent);
00143 
00144   NS_IMETHOD
00145   TransmitAutomaticData()
00146   {
00147     return NS_OK;
00148   }
00149 
00150   NS_IMETHOD
00151   UpdatePresentationData(PRInt32         aScriptLevelIncrement,
00152                          PRUint32        aFlagsValues,
00153                          PRUint32        aFlagsToUpdate);
00154 
00155   NS_IMETHOD
00156   UpdatePresentationDataFromChildAt(PRInt32         aFirstIndex,
00157                                     PRInt32         aLastIndex,
00158                                     PRInt32         aScriptLevelIncrement,
00159                                     PRUint32        aFlagsValues,
00160                                     PRUint32        aFlagsToUpdate)
00161   {
00162     return NS_OK;
00163   }
00164 
00165   NS_IMETHOD
00166   ReResolveScriptStyle(PRInt32 aParentScriptLevel)
00167   {
00168     return NS_OK;
00169   }
00170 
00171   // helper to give a style context suitable for doing the stretching to the
00172   // MathMLChar. Frame classes that use this should make the extra style contexts
00173   // accessible to the Style System via Get/Set AdditionalStyleContext.
00174   static void
00175   ResolveMathMLCharStyle(nsPresContext*  aPresContext,
00176                          nsIContent*      aContent,
00177                          nsStyleContext*  aParenStyleContext,
00178                          nsMathMLChar*    aMathMLChar,
00179                          PRBool           aIsMutableChar);
00180 
00181   // helper to get the mEmbellishData of a frame
00182   // The MathML REC precisely defines an "embellished operator" as:
00183   // - an <mo> element;
00184   // - or one of the elements <msub>, <msup>, <msubsup>, <munder>, <mover>,
00185   //   <munderover>, <mmultiscripts>, <mfrac>, or <semantics>, whose first 
00186   //   argument exists and is an embellished operator;
00187   //- or one of the elements <mstyle>, <mphantom>, or <mpadded>, such that
00188   //   an <mrow> containing the same arguments would be an embellished
00189   //   operator;
00190   // - or an <maction> element whose selected subexpression exists and is an
00191   //   embellished operator;
00192   // - or an <mrow> whose arguments consist (in any order) of one embellished
00193   //   operator and zero or more spacelike elements.
00194   static void
00195   GetEmbellishDataFrom(nsIFrame*        aFrame,
00196                        nsEmbellishData& aEmbellishData);
00197 
00198   // helper to get the presentation data of a frame. If aClimbTree is
00199   // set to true and the frame happens to be surrounded by non-MathML
00200   // helper frames needed for its support, we walk up the frame hierarchy
00201   // until we reach a MathML ancestor or the <root> math element.
00202   static void
00203   GetPresentationDataFrom(nsIFrame*           aFrame,
00204                           nsPresentationData& aPresentationData,
00205                           PRBool              aClimbTree = PR_TRUE);
00206 
00207   // helper to check if a content has an attribute. If content is nsnull or if
00208   // the attribute is not there, check if the attribute is on the mstyle hierarchy
00209   // @return NS_CONTENT_ATTR_HAS_VALUE --if attribute has non-empty value, attr="value"
00210   //         NS_CONTENT_ATTR_NO_VALUE  --if attribute has empty value, attr=""
00211   //         NS_CONTENT_ATTR_NOT_THERE --if attribute is not there
00212   static nsresult
00213   GetAttribute(nsIContent* aContent,
00214                nsIFrame*   aMathMLmstyleFrame,          
00215                nsIAtom*    aAttributeAtom,
00216                nsString&   aValue);
00217 
00218   // utilities to parse and retrieve numeric values in CSS units
00219   // All values are stored in twips.
00220   static PRBool
00221   ParseNumericValue(nsString&   aString,
00222                     nsCSSValue& aCSSValue);
00223 
00224   static nscoord 
00225   CalcLength(nsPresContext*   aPresContext,
00226              nsStyleContext*   aStyleContext,
00227              const nsCSSValue& aCSSValue);
00228 
00229   static PRBool
00230   ParseNamedSpaceValue(nsIFrame*   aMathMLmstyleFrame,
00231                        nsString&   aString,
00232                        nsCSSValue& aCSSValue);
00233 
00234   static eMathMLFrameType
00235   GetMathMLFrameTypeFor(nsIFrame* aFrame)
00236   {
00237     if (aFrame->IsFrameOfType(nsIFrame::eMathML)) {
00238       nsIMathMLFrame* mathMLFrame;
00239       CallQueryInterface(aFrame, &mathMLFrame);
00240       if (mathMLFrame)
00241         return mathMLFrame->GetMathMLFrameType();
00242     }
00243     return eMathMLFrameType_UNKNOWN;
00244   }
00245 
00246   // estimate of the italic correction
00247   static void
00248   GetItalicCorrection(nsBoundingMetrics& aBoundingMetrics,
00249                       nscoord&           aItalicCorrection)
00250   {
00251     aItalicCorrection = aBoundingMetrics.rightBearing - aBoundingMetrics.width;
00252     if (0 > aItalicCorrection) {
00253       aItalicCorrection = 0;
00254     }
00255   }
00256 
00257   static void
00258   GetItalicCorrection(nsBoundingMetrics& aBoundingMetrics,
00259                       nscoord&           aLeftItalicCorrection,
00260                       nscoord&           aRightItalicCorrection)
00261   {
00262     aRightItalicCorrection = aBoundingMetrics.rightBearing - aBoundingMetrics.width;
00263     if (0 > aRightItalicCorrection) {
00264       aRightItalicCorrection = 0;
00265     }
00266     aLeftItalicCorrection = -aBoundingMetrics.leftBearing;
00267     if (0 > aLeftItalicCorrection) {
00268       aLeftItalicCorrection = 0;
00269     }
00270   }
00271 
00272   // helper methods for getting sup/subdrop's from a child
00273   static void 
00274   GetSubDropFromChild(nsIFrame*       aChild,
00275                       nscoord&        aSubDrop) 
00276   {
00277     const nsStyleFont* font = aChild->GetStyleFont();
00278     nsCOMPtr<nsIFontMetrics> fm = aChild->GetPresContext()->GetMetricsFor(
00279                                                               font->mFont);
00280     GetSubDrop(fm, aSubDrop);
00281   }
00282 
00283   static void 
00284   GetSupDropFromChild(nsIFrame*       aChild,
00285                       nscoord&        aSupDrop) 
00286   {
00287     const nsStyleFont* font = aChild->GetStyleFont();
00288     nsCOMPtr<nsIFontMetrics> fm = aChild->GetPresContext()->GetMetricsFor(
00289                                                               font->mFont);
00290     GetSupDrop(fm, aSupDrop);
00291   }
00292 
00293   static void
00294   GetSkewCorrectionFromChild(nsIFrame*       aChild,
00295                              nscoord&        aSkewCorrection) 
00296   {
00297     // default is 0
00298     // individual classes should over-ride this method if necessary
00299     aSkewCorrection = 0;
00300   }
00301 
00302   // 2 levels of subscript shifts
00303   static void
00304   GetSubScriptShifts(nsIFontMetrics* fm, 
00305                      nscoord&        aSubScriptShift1, 
00306                      nscoord&        aSubScriptShift2)
00307   {
00308     nscoord xHeight;
00309     fm->GetXHeight(xHeight);
00310     aSubScriptShift1 = NSToCoordRound(150.000f/430.556f * xHeight);
00311     aSubScriptShift2 = NSToCoordRound(247.217f/430.556f * xHeight);
00312   }
00313 
00314   // 3 levels of superscript shifts
00315   static void
00316   GetSupScriptShifts(nsIFontMetrics* fm, 
00317                      nscoord&        aSupScriptShift1, 
00318                      nscoord&        aSupScriptShift2, 
00319                      nscoord&        aSupScriptShift3)
00320   {
00321     nscoord xHeight;
00322     fm->GetXHeight(xHeight);
00323     aSupScriptShift1 = NSToCoordRound(412.892f/430.556f * xHeight);
00324     aSupScriptShift2 = NSToCoordRound(362.892f/430.556f * xHeight);
00325     aSupScriptShift3 = NSToCoordRound(288.889f/430.556f * xHeight);
00326   }
00327 
00328   // these are TeX specific params not found in ordinary fonts
00329 
00330   static void
00331   GetSubDrop(nsIFontMetrics* fm,
00332              nscoord&        aSubDrop)
00333   {
00334     nscoord xHeight;
00335     fm->GetXHeight(xHeight);
00336     aSubDrop = NSToCoordRound(50.000f/430.556f * xHeight);
00337   }
00338 
00339   static void
00340   GetSupDrop(nsIFontMetrics* fm,
00341              nscoord&        aSupDrop)
00342   {
00343     nscoord xHeight;
00344     fm->GetXHeight(xHeight);
00345     aSupDrop = NSToCoordRound(386.108f/430.556f * xHeight);
00346   }
00347 
00348   static void
00349   GetNumeratorShifts(nsIFontMetrics* fm, 
00350                      nscoord&        numShift1, 
00351                      nscoord&        numShift2, 
00352                      nscoord&        numShift3)
00353   {
00354     nscoord xHeight;
00355     fm->GetXHeight(xHeight);
00356     numShift1 = NSToCoordRound(676.508f/430.556f * xHeight);
00357     numShift2 = NSToCoordRound(393.732f/430.556f * xHeight);
00358     numShift3 = NSToCoordRound(443.731f/430.556f * xHeight);
00359   }
00360 
00361   static void
00362   GetDenominatorShifts(nsIFontMetrics* fm, 
00363                        nscoord&        denShift1, 
00364                        nscoord&        denShift2)
00365   {
00366     nscoord xHeight;
00367     fm->GetXHeight(xHeight);
00368     denShift1 = NSToCoordRound(685.951f/430.556f * xHeight);
00369     denShift2 = NSToCoordRound(344.841f/430.556f * xHeight);
00370   }
00371 
00372   static void
00373   GetEmHeight(nsIFontMetrics* fm,
00374               nscoord&        emHeight)
00375   {
00376 #if 0 
00377     // should switch to this API in order to scale with changes of TextZoom
00378     fm->GetEmHeight(emHeight);
00379 #else
00380     emHeight = NSToCoordRound(float(fm->Font().size));
00381 #endif
00382   }
00383 
00384   static void
00385   GetAxisHeight (nsIFontMetrics* fm,
00386                  nscoord&        axisHeight)
00387   {
00388     fm->GetXHeight (axisHeight);
00389     axisHeight = NSToCoordRound(250.000f/430.556f * axisHeight);
00390   }
00391 
00392   static void
00393   GetBigOpSpacings(nsIFontMetrics* fm, 
00394                    nscoord&        bigOpSpacing1,
00395                    nscoord&        bigOpSpacing2,
00396                    nscoord&        bigOpSpacing3,
00397                    nscoord&        bigOpSpacing4,
00398                    nscoord&        bigOpSpacing5)
00399   {
00400     nscoord xHeight;
00401     fm->GetXHeight(xHeight);
00402     bigOpSpacing1 = NSToCoordRound(111.111f/430.556f * xHeight);
00403     bigOpSpacing2 = NSToCoordRound(166.667f/430.556f * xHeight);
00404     bigOpSpacing3 = NSToCoordRound(200.000f/430.556f * xHeight);
00405     bigOpSpacing4 = NSToCoordRound(600.000f/430.556f * xHeight);
00406     bigOpSpacing5 = NSToCoordRound(100.000f/430.556f * xHeight);
00407   }
00408 
00409   static void
00410   GetRuleThickness(nsIFontMetrics* fm,
00411                    nscoord&        ruleThickness)
00412   {
00413     nscoord xHeight;
00414     fm->GetXHeight(xHeight);
00415     ruleThickness = NSToCoordRound(40.000f/430.556f * xHeight);
00416   }
00417 
00418   // Some parameters are not accurately obtained using the x-height.
00419   // Here are some slower variants to obtain the desired metrics
00420   // by actually measuring some characters
00421   static void
00422   GetRuleThickness(nsIRenderingContext& aRenderingContext, 
00423                    nsIFontMetrics*      aFontMetrics,
00424                    nscoord&             aRuleThickness);
00425 
00426   static void
00427   GetAxisHeight(nsIRenderingContext& aRenderingContext, 
00428                 nsIFontMetrics*      aFontMetrics,
00429                 nscoord&             aAxisHeight);
00430 
00431   // ================
00432   // helpers to map attributes into CSS rules (work-around to bug 69409 which
00433   // is not scheduled to be fixed anytime soon)
00434   static PRInt32
00435   MapAttributesIntoCSS(nsPresContext* aPresContext,
00436                        nsIContent*     aContent);
00437   static PRInt32
00438   MapAttributesIntoCSS(nsPresContext* aPresContext,
00439                        nsIFrame*       aFrame);
00440 
00441 protected:
00442   // information about the presentation policy of the frame
00443   nsPresentationData mPresentationData;
00444 
00445   // information about a container that is an embellished operator
00446   nsEmbellishData mEmbellishData;
00447   
00448   // Metrics that _exactly_ enclose the text of the frame
00449   nsBoundingMetrics mBoundingMetrics;
00450   
00451   // Reference point of the frame: mReference.y is the baseline
00452   nsPoint mReference; 
00453 };
00454 
00455 #endif /* nsMathMLFrame_h___ */