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