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