nsMathMLFrame.h (10945B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef nsMathMLFrame_h___ 8 #define nsMathMLFrame_h___ 9 10 #include "nsBoundingMetrics.h" 11 #include "nsFontMetrics.h" 12 #include "nsIFrame.h" 13 #include "nsIMathMLFrame.h" 14 #include "nsMathMLOperators.h" 15 16 class nsMathMLChar; 17 class nsCSSValue; 18 19 namespace mozilla { 20 class nsDisplayListBuilder; 21 class nsDisplayListSet; 22 } // namespace mozilla 23 24 // Concrete base class with default methods that derived MathML frames can 25 // override 26 class nsMathMLFrame : public nsIMathMLFrame { 27 public: 28 // nsIMathMLFrame --- 29 30 bool IsSpaceLike() override { 31 return mPresentationData.flags.contains(MathMLPresentationFlag::SpaceLike); 32 } 33 34 NS_IMETHOD 35 GetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics) override { 36 aBoundingMetrics = mBoundingMetrics; 37 return NS_OK; 38 } 39 40 NS_IMETHOD 41 SetBoundingMetrics(const nsBoundingMetrics& aBoundingMetrics) override { 42 mBoundingMetrics = aBoundingMetrics; 43 return NS_OK; 44 } 45 46 NS_IMETHOD 47 SetReference(const nsPoint& aReference) override { 48 mReference = aReference; 49 return NS_OK; 50 } 51 52 MathMLFrameType GetMathMLFrameType() override; 53 54 NS_IMETHOD 55 Stretch(mozilla::gfx::DrawTarget* aDrawTarget, 56 nsStretchDirection aStretchDirection, 57 nsBoundingMetrics& aContainerSize, 58 mozilla::ReflowOutput& aDesiredStretchSize) override { 59 return NS_OK; 60 } 61 62 NS_IMETHOD 63 GetEmbellishData(nsEmbellishData& aEmbellishData) override { 64 aEmbellishData = mEmbellishData; 65 return NS_OK; 66 } 67 68 NS_IMETHOD 69 GetPresentationData(nsPresentationData& aPresentationData) override { 70 aPresentationData = mPresentationData; 71 return NS_OK; 72 } 73 74 NS_IMETHOD 75 InheritAutomaticData(nsIFrame* aParent) override; 76 77 NS_IMETHOD 78 TransmitAutomaticData() override { return NS_OK; } 79 80 NS_IMETHOD 81 UpdatePresentationData(MathMLPresentationFlags aFlagsValues, 82 MathMLPresentationFlags aFlagsToUpdate) override; 83 84 NS_IMETHOD 85 UpdatePresentationDataFromChildAt( 86 int32_t aFirstIndex, int32_t aLastIndex, 87 MathMLPresentationFlags aFlagsValues, 88 MathMLPresentationFlags aFlagsToUpdate) override { 89 return NS_OK; 90 } 91 92 uint8_t ScriptIncrement(nsIFrame* aFrame) override { return 0; } 93 94 bool IsMrowLike() override { return false; } 95 96 // helper to get the mEmbellishData of a frame 97 // The MathML REC precisely defines an "embellished operator" as: 98 // - an <mo> element; 99 // - or one of the elements <msub>, <msup>, <msubsup>, <munder>, <mover>, 100 // <munderover>, <mmultiscripts>, <mfrac>, or <semantics>, whose first 101 // argument exists and is an embellished operator; 102 //- or one of the elements <mstyle>, <mphantom>, or <mpadded>, such that 103 // an <mrow> containing the same arguments would be an embellished 104 // operator; 105 // - or an <maction> element whose selected subexpression exists and is an 106 // embellished operator; 107 // - or an <mrow> whose arguments consist (in any order) of one embellished 108 // operator and zero or more spacelike elements. 109 static void GetEmbellishDataFrom(nsIFrame* aFrame, 110 nsEmbellishData& aEmbellishData); 111 112 // helper to get the presentation data of a frame. If aClimbTree is 113 // set to true and the frame happens to be surrounded by non-MathML 114 // helper frames needed for its support, we walk up the frame hierarchy 115 // until we reach a MathML ancestor or the <root> math element. 116 static void GetPresentationDataFrom(nsIFrame* aFrame, 117 nsPresentationData& aPresentationData, 118 bool aClimbTree = true); 119 120 // utilities to parse and retrieve numeric values in CSS units 121 // All values are stored in twips. 122 // @pre aLengthValue is the default length value of the attribute. 123 // @post aLengthValue is the length value computed from the attribute. 124 static void ParseAndCalcNumericValue(const nsString& aString, 125 nscoord* aLengthValue, uint32_t aFlags, 126 float aFontSizeInflation, 127 nsIFrame* aFrame); 128 129 static nscoord CalcLength(const nsCSSValue& aCSSValue, 130 float aFontSizeInflation, nsIFrame* aFrame); 131 132 static MathMLFrameType GetMathMLFrameTypeFor(nsIFrame* aFrame) { 133 if (aFrame->IsMathMLFrame()) { 134 if (nsIMathMLFrame* mathMLFrame = do_QueryFrame(aFrame)) { 135 return mathMLFrame->GetMathMLFrameType(); 136 } 137 } 138 return MathMLFrameType::Unknown; 139 } 140 141 // estimate of the italic correction 142 static void GetItalicCorrection(nsBoundingMetrics& aBoundingMetrics, 143 nscoord& aItalicCorrection) { 144 aItalicCorrection = aBoundingMetrics.rightBearing - aBoundingMetrics.width; 145 if (0 > aItalicCorrection) { 146 aItalicCorrection = 0; 147 } 148 } 149 150 static void GetItalicCorrection(nsBoundingMetrics& aBoundingMetrics, 151 nscoord& aLeftItalicCorrection, 152 nscoord& aRightItalicCorrection) { 153 aRightItalicCorrection = 154 aBoundingMetrics.rightBearing - aBoundingMetrics.width; 155 if (0 > aRightItalicCorrection) { 156 aRightItalicCorrection = 0; 157 } 158 aLeftItalicCorrection = -aBoundingMetrics.leftBearing; 159 if (0 > aLeftItalicCorrection) { 160 aLeftItalicCorrection = 0; 161 } 162 } 163 164 // helper methods for getting sup/subdrop's from a child 165 static void GetSubDropFromChild(nsIFrame* aChild, nscoord& aSubDrop, 166 float aFontSizeInflation); 167 168 static void GetSupDropFromChild(nsIFrame* aChild, nscoord& aSupDrop, 169 float aFontSizeInflation); 170 171 static void GetSkewCorrectionFromChild(nsIFrame* aChild, 172 nscoord& aSkewCorrection) { 173 // default is 0 174 // individual classes should over-ride this method if necessary 175 aSkewCorrection = 0; 176 } 177 178 // 2 levels of subscript shifts 179 static void GetSubScriptShifts(nsFontMetrics* fm, nscoord& aSubScriptShift1, 180 nscoord& aSubScriptShift2) { 181 nscoord xHeight = fm->XHeight(); 182 aSubScriptShift1 = NSToCoordRound(150.000f / 430.556f * xHeight); 183 aSubScriptShift2 = NSToCoordRound(247.217f / 430.556f * xHeight); 184 } 185 186 // 3 levels of superscript shifts 187 static void GetSupScriptShifts(nsFontMetrics* fm, nscoord& aSupScriptShift1, 188 nscoord& aSupScriptShift2, 189 nscoord& aSupScriptShift3) { 190 nscoord xHeight = fm->XHeight(); 191 aSupScriptShift1 = NSToCoordRound(412.892f / 430.556f * xHeight); 192 aSupScriptShift2 = NSToCoordRound(362.892f / 430.556f * xHeight); 193 aSupScriptShift3 = NSToCoordRound(288.889f / 430.556f * xHeight); 194 } 195 196 // these are TeX specific params not found in ordinary fonts 197 198 static void GetSubDrop(nsFontMetrics* fm, nscoord& aSubDrop) { 199 nscoord xHeight = fm->XHeight(); 200 aSubDrop = NSToCoordRound(50.000f / 430.556f * xHeight); 201 } 202 203 static void GetSupDrop(nsFontMetrics* fm, nscoord& aSupDrop) { 204 nscoord xHeight = fm->XHeight(); 205 aSupDrop = NSToCoordRound(386.108f / 430.556f * xHeight); 206 } 207 208 static void GetNumeratorShifts(nsFontMetrics* fm, nscoord& numShift1, 209 nscoord& numShift2, nscoord& numShift3) { 210 nscoord xHeight = fm->XHeight(); 211 numShift1 = NSToCoordRound(676.508f / 430.556f * xHeight); 212 numShift2 = NSToCoordRound(393.732f / 430.556f * xHeight); 213 numShift3 = NSToCoordRound(443.731f / 430.556f * xHeight); 214 } 215 216 static void GetDenominatorShifts(nsFontMetrics* fm, nscoord& denShift1, 217 nscoord& denShift2) { 218 nscoord xHeight = fm->XHeight(); 219 denShift1 = NSToCoordRound(685.951f / 430.556f * xHeight); 220 denShift2 = NSToCoordRound(344.841f / 430.556f * xHeight); 221 } 222 223 static void GetEmHeight(nsFontMetrics* fm, nscoord& emHeight) { 224 #if 0 225 // should switch to this API in order to scale with changes of TextZoom 226 emHeight = fm->EmHeight(); 227 #else 228 emHeight = fm->Font().size.ToAppUnits(); 229 #endif 230 } 231 232 static void GetAxisHeight(nsFontMetrics* fm, nscoord& axisHeight) { 233 axisHeight = NSToCoordRound(250.000f / 430.556f * fm->XHeight()); 234 } 235 236 static void GetBigOpSpacings(nsFontMetrics* fm, nscoord& bigOpSpacing1, 237 nscoord& bigOpSpacing2, nscoord& bigOpSpacing3, 238 nscoord& bigOpSpacing4, nscoord& bigOpSpacing5) { 239 nscoord xHeight = fm->XHeight(); 240 bigOpSpacing1 = NSToCoordRound(111.111f / 430.556f * xHeight); 241 bigOpSpacing2 = NSToCoordRound(166.667f / 430.556f * xHeight); 242 bigOpSpacing3 = NSToCoordRound(200.000f / 430.556f * xHeight); 243 bigOpSpacing4 = NSToCoordRound(600.000f / 430.556f * xHeight); 244 bigOpSpacing5 = NSToCoordRound(100.000f / 430.556f * xHeight); 245 } 246 247 static void GetRuleThickness(nsFontMetrics* fm, nscoord& ruleThickness) { 248 nscoord xHeight = fm->XHeight(); 249 ruleThickness = NSToCoordRound(40.000f / 430.556f * xHeight); 250 } 251 252 // Some parameters are not accurately obtained using the x-height. 253 // Here are some slower variants to obtain the desired metrics 254 // by actually measuring some characters 255 static void GetRuleThickness(mozilla::gfx::DrawTarget* aDrawTarget, 256 nsFontMetrics* aFontMetrics, 257 nscoord& aRuleThickness); 258 259 static void GetAxisHeight(mozilla::gfx::DrawTarget* aDrawTarget, 260 nsFontMetrics* aFontMetrics, nscoord& aAxisHeight); 261 262 static void GetRadicalParameters(nsFontMetrics* aFontMetrics, 263 bool aDisplayStyle, 264 nscoord& aRadicalRuleThickness, 265 nscoord& aRadicalExtraAscender, 266 nscoord& aRadicalVerticalGap); 267 268 protected: 269 /** 270 * Display a solid rectangle in the frame's text color. Used for drawing 271 * fraction separators and root/sqrt overbars. 272 */ 273 void DisplayBar(mozilla::nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, 274 const nsRect& aRect, const mozilla::nsDisplayListSet& aLists, 275 uint32_t aIndex = 0); 276 277 // information about the presentation policy of the frame 278 nsPresentationData mPresentationData; 279 280 // information about a container that is an embellished operator 281 nsEmbellishData mEmbellishData; 282 283 // Metrics that _exactly_ enclose the text of the frame 284 nsBoundingMetrics mBoundingMetrics; 285 286 // Reference point of the frame: mReference.y is the baseline 287 nsPoint mReference; 288 }; 289 290 #endif /* nsMathMLFrame_h___ */