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/. */
7 #ifndef nsMathMLFrame_h___
8 #define nsMathMLFrame_h___
10 #include "mozilla/Attributes.h"
11 #include "nsFontMetrics.h"
12 #include "nsMathMLOperators.h"
13 #include "nsIMathMLFrame.h"
14 #include "nsBoundingMetrics.h"
21 class nsDisplayListBuilder
;
22 class nsDisplayListSet
;
23 } // namespace mozilla
25 // Concrete base class with default methods that derived MathML frames can
27 class nsMathMLFrame
: public nsIMathMLFrame
{
31 virtual bool IsSpaceLike() override
{
32 return NS_MATHML_IS_SPACE_LIKE(mPresentationData
.flags
);
36 GetBoundingMetrics(nsBoundingMetrics
& aBoundingMetrics
) override
{
37 aBoundingMetrics
= mBoundingMetrics
;
42 SetBoundingMetrics(const nsBoundingMetrics
& aBoundingMetrics
) override
{
43 mBoundingMetrics
= aBoundingMetrics
;
48 SetReference(const nsPoint
& aReference
) override
{
49 mReference
= aReference
;
53 virtual eMathMLFrameType
GetMathMLFrameType() override
;
56 Stretch(mozilla::gfx::DrawTarget
* aDrawTarget
,
57 nsStretchDirection aStretchDirection
,
58 nsBoundingMetrics
& aContainerSize
,
59 mozilla::ReflowOutput
& aDesiredStretchSize
) override
{
64 GetEmbellishData(nsEmbellishData
& aEmbellishData
) override
{
65 aEmbellishData
= mEmbellishData
;
70 GetPresentationData(nsPresentationData
& aPresentationData
) override
{
71 aPresentationData
= mPresentationData
;
76 InheritAutomaticData(nsIFrame
* aParent
) override
;
79 TransmitAutomaticData() override
{ return NS_OK
; }
82 UpdatePresentationData(uint32_t aFlagsValues
,
83 uint32_t aFlagsToUpdate
) override
;
86 UpdatePresentationDataFromChildAt(int32_t aFirstIndex
, int32_t aLastIndex
,
87 uint32_t aFlagsValues
,
88 uint32_t aFlagsToUpdate
) override
{
92 uint8_t ScriptIncrement(nsIFrame
* aFrame
) override
{ return 0; }
94 bool IsMrowLike() override
{ return false; }
96 // helper to get the mEmbellishData of a frame
97 // The MathML REC precisely defines an "embellished operator" as:
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
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
);
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);
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 ParseNumericValue(const nsString
& aString
, nscoord
* aLengthValue
,
125 uint32_t aFlags
, nsPresContext
* aPresContext
,
126 mozilla::ComputedStyle
* aComputedStyle
,
127 float aFontSizeInflation
);
129 static nscoord
CalcLength(nsPresContext
* aPresContext
,
130 mozilla::ComputedStyle
* aComputedStyle
,
131 const nsCSSValue
& aCSSValue
,
132 float aFontSizeInflation
);
134 static eMathMLFrameType
GetMathMLFrameTypeFor(nsIFrame
* aFrame
) {
135 if (aFrame
->IsFrameOfType(nsIFrame::eMathML
)) {
136 nsIMathMLFrame
* mathMLFrame
= do_QueryFrame(aFrame
);
137 if (mathMLFrame
) return mathMLFrame
->GetMathMLFrameType();
139 return eMathMLFrameType_UNKNOWN
;
142 // estimate of the italic correction
143 static void GetItalicCorrection(nsBoundingMetrics
& aBoundingMetrics
,
144 nscoord
& aItalicCorrection
) {
145 aItalicCorrection
= aBoundingMetrics
.rightBearing
- aBoundingMetrics
.width
;
146 if (0 > aItalicCorrection
) {
147 aItalicCorrection
= 0;
151 static void GetItalicCorrection(nsBoundingMetrics
& aBoundingMetrics
,
152 nscoord
& aLeftItalicCorrection
,
153 nscoord
& aRightItalicCorrection
) {
154 aRightItalicCorrection
=
155 aBoundingMetrics
.rightBearing
- aBoundingMetrics
.width
;
156 if (0 > aRightItalicCorrection
) {
157 aRightItalicCorrection
= 0;
159 aLeftItalicCorrection
= -aBoundingMetrics
.leftBearing
;
160 if (0 > aLeftItalicCorrection
) {
161 aLeftItalicCorrection
= 0;
165 // helper methods for getting sup/subdrop's from a child
166 static void GetSubDropFromChild(nsIFrame
* aChild
, nscoord
& aSubDrop
,
167 float aFontSizeInflation
);
169 static void GetSupDropFromChild(nsIFrame
* aChild
, nscoord
& aSupDrop
,
170 float aFontSizeInflation
);
172 static void GetSkewCorrectionFromChild(nsIFrame
* aChild
,
173 nscoord
& aSkewCorrection
) {
175 // individual classes should over-ride this method if necessary
179 // 2 levels of subscript shifts
180 static void GetSubScriptShifts(nsFontMetrics
* fm
, nscoord
& aSubScriptShift1
,
181 nscoord
& aSubScriptShift2
) {
182 nscoord xHeight
= fm
->XHeight();
183 aSubScriptShift1
= NSToCoordRound(150.000f
/ 430.556f
* xHeight
);
184 aSubScriptShift2
= NSToCoordRound(247.217f
/ 430.556f
* xHeight
);
187 // 3 levels of superscript shifts
188 static void GetSupScriptShifts(nsFontMetrics
* fm
, nscoord
& aSupScriptShift1
,
189 nscoord
& aSupScriptShift2
,
190 nscoord
& aSupScriptShift3
) {
191 nscoord xHeight
= fm
->XHeight();
192 aSupScriptShift1
= NSToCoordRound(412.892f
/ 430.556f
* xHeight
);
193 aSupScriptShift2
= NSToCoordRound(362.892f
/ 430.556f
* xHeight
);
194 aSupScriptShift3
= NSToCoordRound(288.889f
/ 430.556f
* xHeight
);
197 // these are TeX specific params not found in ordinary fonts
199 static void GetSubDrop(nsFontMetrics
* fm
, nscoord
& aSubDrop
) {
200 nscoord xHeight
= fm
->XHeight();
201 aSubDrop
= NSToCoordRound(50.000f
/ 430.556f
* xHeight
);
204 static void GetSupDrop(nsFontMetrics
* fm
, nscoord
& aSupDrop
) {
205 nscoord xHeight
= fm
->XHeight();
206 aSupDrop
= NSToCoordRound(386.108f
/ 430.556f
* xHeight
);
209 static void GetNumeratorShifts(nsFontMetrics
* fm
, nscoord
& numShift1
,
210 nscoord
& numShift2
, nscoord
& numShift3
) {
211 nscoord xHeight
= fm
->XHeight();
212 numShift1
= NSToCoordRound(676.508f
/ 430.556f
* xHeight
);
213 numShift2
= NSToCoordRound(393.732f
/ 430.556f
* xHeight
);
214 numShift3
= NSToCoordRound(443.731f
/ 430.556f
* xHeight
);
217 static void GetDenominatorShifts(nsFontMetrics
* fm
, nscoord
& denShift1
,
218 nscoord
& denShift2
) {
219 nscoord xHeight
= fm
->XHeight();
220 denShift1
= NSToCoordRound(685.951f
/ 430.556f
* xHeight
);
221 denShift2
= NSToCoordRound(344.841f
/ 430.556f
* xHeight
);
224 static void GetEmHeight(nsFontMetrics
* fm
, nscoord
& emHeight
) {
226 // should switch to this API in order to scale with changes of TextZoom
227 emHeight
= fm
->EmHeight();
229 emHeight
= fm
->Font().size
.ToAppUnits();
233 static void GetAxisHeight(nsFontMetrics
* fm
, nscoord
& axisHeight
) {
234 axisHeight
= NSToCoordRound(250.000f
/ 430.556f
* fm
->XHeight());
237 static void GetBigOpSpacings(nsFontMetrics
* fm
, nscoord
& bigOpSpacing1
,
238 nscoord
& bigOpSpacing2
, nscoord
& bigOpSpacing3
,
239 nscoord
& bigOpSpacing4
, nscoord
& bigOpSpacing5
) {
240 nscoord xHeight
= fm
->XHeight();
241 bigOpSpacing1
= NSToCoordRound(111.111f
/ 430.556f
* xHeight
);
242 bigOpSpacing2
= NSToCoordRound(166.667f
/ 430.556f
* xHeight
);
243 bigOpSpacing3
= NSToCoordRound(200.000f
/ 430.556f
* xHeight
);
244 bigOpSpacing4
= NSToCoordRound(600.000f
/ 430.556f
* xHeight
);
245 bigOpSpacing5
= NSToCoordRound(100.000f
/ 430.556f
* xHeight
);
248 static void GetRuleThickness(nsFontMetrics
* fm
, nscoord
& ruleThickness
) {
249 nscoord xHeight
= fm
->XHeight();
250 ruleThickness
= NSToCoordRound(40.000f
/ 430.556f
* xHeight
);
253 // Some parameters are not accurately obtained using the x-height.
254 // Here are some slower variants to obtain the desired metrics
255 // by actually measuring some characters
256 static void GetRuleThickness(mozilla::gfx::DrawTarget
* aDrawTarget
,
257 nsFontMetrics
* aFontMetrics
,
258 nscoord
& aRuleThickness
);
260 static void GetAxisHeight(mozilla::gfx::DrawTarget
* aDrawTarget
,
261 nsFontMetrics
* aFontMetrics
, nscoord
& aAxisHeight
);
263 static void GetRadicalParameters(nsFontMetrics
* aFontMetrics
,
265 nscoord
& aRadicalRuleThickness
,
266 nscoord
& aRadicalExtraAscender
,
267 nscoord
& aRadicalVerticalGap
);
270 #if defined(DEBUG) && defined(SHOW_BOUNDING_BOX)
271 void DisplayBoundingMetrics(mozilla::nsDisplayListBuilder
* aBuilder
,
272 nsIFrame
* aFrame
, const nsPoint
& aPt
,
273 const nsBoundingMetrics
& aMetrics
,
274 const nsDisplayListSet
& aLists
);
278 * Display a solid rectangle in the frame's text color. Used for drawing
279 * fraction separators and root/sqrt overbars.
281 void DisplayBar(mozilla::nsDisplayListBuilder
* aBuilder
, nsIFrame
* aFrame
,
282 const nsRect
& aRect
, const mozilla::nsDisplayListSet
& aLists
,
283 uint32_t aIndex
= 0);
285 // information about the presentation policy of the frame
286 nsPresentationData mPresentationData
;
288 // information about a container that is an embellished operator
289 nsEmbellishData mEmbellishData
;
291 // Metrics that _exactly_ enclose the text of the frame
292 nsBoundingMetrics mBoundingMetrics
;
294 // Reference point of the frame: mReference.y is the baseline
298 #endif /* nsMathMLFrame_h___ */