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