1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Mozilla MathML Project.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * The University Of Queensland.
19 : * Portions created by the Initial Developer are Copyright (C) 1999
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Roger B. Sidje <rbs@maths.uq.edu.au>
24 : * Frederic Wang <fred.wang@free.fr>
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either of the GNU General Public License Version 2 or later (the "GPL"),
28 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #ifndef nsMathMLFrame_h___
41 : #define nsMathMLFrame_h___
42 :
43 : #include "nsCOMPtr.h"
44 : #include "nsPresContext.h"
45 : #include "nsFontMetrics.h"
46 : #include "nsStyleContext.h"
47 : #include "nsMathMLAtoms.h"
48 : #include "nsMathMLOperators.h"
49 : #include "nsIMathMLFrame.h"
50 : #include "nsFrame.h"
51 : #include "nsCSSValue.h"
52 : #include "nsMathMLElement.h"
53 : #include "nsLayoutUtils.h"
54 :
55 : class nsMathMLChar;
56 :
57 : // Concrete base class with default methods that derived MathML frames can override
58 0 : class nsMathMLFrame : public nsIMathMLFrame {
59 : public:
60 :
61 : // nsIMathMLFrame ---
62 :
63 : virtual bool
64 0 : IsSpaceLike() {
65 0 : return NS_MATHML_IS_SPACE_LIKE(mPresentationData.flags);
66 : }
67 :
68 : NS_IMETHOD
69 0 : GetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics) {
70 0 : aBoundingMetrics = mBoundingMetrics;
71 0 : return NS_OK;
72 : }
73 :
74 : NS_IMETHOD
75 0 : SetBoundingMetrics(const nsBoundingMetrics& aBoundingMetrics) {
76 0 : mBoundingMetrics = aBoundingMetrics;
77 0 : return NS_OK;
78 : }
79 :
80 : NS_IMETHOD
81 0 : SetReference(const nsPoint& aReference) {
82 0 : mReference = aReference;
83 0 : return NS_OK;
84 : }
85 :
86 : virtual eMathMLFrameType GetMathMLFrameType();
87 :
88 : NS_IMETHOD
89 0 : Stretch(nsRenderingContext& aRenderingContext,
90 : nsStretchDirection aStretchDirection,
91 : nsBoundingMetrics& aContainerSize,
92 : nsHTMLReflowMetrics& aDesiredStretchSize)
93 : {
94 0 : return NS_OK;
95 : }
96 :
97 : NS_IMETHOD
98 0 : GetEmbellishData(nsEmbellishData& aEmbellishData) {
99 0 : aEmbellishData = mEmbellishData;
100 0 : return NS_OK;
101 : }
102 :
103 : NS_IMETHOD
104 0 : GetPresentationData(nsPresentationData& aPresentationData) {
105 0 : aPresentationData = mPresentationData;
106 0 : return NS_OK;
107 : }
108 :
109 : NS_IMETHOD
110 : InheritAutomaticData(nsIFrame* aParent);
111 :
112 : NS_IMETHOD
113 0 : TransmitAutomaticData()
114 : {
115 0 : return NS_OK;
116 : }
117 :
118 : NS_IMETHOD
119 : UpdatePresentationData(PRUint32 aFlagsValues,
120 : PRUint32 aFlagsToUpdate);
121 :
122 : NS_IMETHOD
123 0 : UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex,
124 : PRInt32 aLastIndex,
125 : PRUint32 aFlagsValues,
126 : PRUint32 aFlagsToUpdate)
127 : {
128 0 : return NS_OK;
129 : }
130 :
131 : // helper to give a style context suitable for doing the stretching to the
132 : // MathMLChar. Frame classes that use this should make the extra style contexts
133 : // accessible to the Style System via Get/Set AdditionalStyleContext.
134 : static void
135 : ResolveMathMLCharStyle(nsPresContext* aPresContext,
136 : nsIContent* aContent,
137 : nsStyleContext* aParenStyleContext,
138 : nsMathMLChar* aMathMLChar,
139 : bool aIsMutableChar);
140 :
141 : // helper to get the mEmbellishData of a frame
142 : // The MathML REC precisely defines an "embellished operator" as:
143 : // - an <mo> element;
144 : // - or one of the elements <msub>, <msup>, <msubsup>, <munder>, <mover>,
145 : // <munderover>, <mmultiscripts>, <mfrac>, or <semantics>, whose first
146 : // argument exists and is an embellished operator;
147 : //- or one of the elements <mstyle>, <mphantom>, or <mpadded>, such that
148 : // an <mrow> containing the same arguments would be an embellished
149 : // operator;
150 : // - or an <maction> element whose selected subexpression exists and is an
151 : // embellished operator;
152 : // - or an <mrow> whose arguments consist (in any order) of one embellished
153 : // operator and zero or more spacelike elements.
154 : static void
155 : GetEmbellishDataFrom(nsIFrame* aFrame,
156 : nsEmbellishData& aEmbellishData);
157 :
158 : // helper to get the presentation data of a frame. If aClimbTree is
159 : // set to true and the frame happens to be surrounded by non-MathML
160 : // helper frames needed for its support, we walk up the frame hierarchy
161 : // until we reach a MathML ancestor or the <root> math element.
162 : static void
163 : GetPresentationDataFrom(nsIFrame* aFrame,
164 : nsPresentationData& aPresentationData,
165 : bool aClimbTree = true);
166 :
167 : // helper used by <mstyle> and <mtable> to see if they have a displaystyle attribute
168 : static void
169 : FindAttrDisplaystyle(nsIContent* aContent,
170 : nsPresentationData& aPresentationData);
171 :
172 : // helper used to see if an element has a dir attribute
173 : static void
174 : FindAttrDirectionality(nsIContent* aContent,
175 : nsPresentationData& aPresentationData);
176 :
177 : // helper to check if a content has an attribute. If content is nsnull or if
178 : // the attribute is not there, check if the attribute is on the mstyle hierarchy
179 : // @return true --if attribute exists
180 : // false --if attribute doesn't exist
181 : static bool
182 : GetAttribute(nsIContent* aContent,
183 : nsIFrame* aMathMLmstyleFrame,
184 : nsIAtom* aAttributeAtom,
185 : nsString& aValue);
186 :
187 : // utilities to parse and retrieve numeric values in CSS units
188 : // All values are stored in twips.
189 : static bool
190 0 : ParseNumericValue(const nsString& aString,
191 : nsCSSValue& aCSSValue) {
192 : return nsMathMLElement::ParseNumericValue(aString, aCSSValue,
193 : nsMathMLElement::PARSE_ALLOW_NEGATIVE |
194 0 : nsMathMLElement::PARSE_ALLOW_UNITLESS);
195 : }
196 :
197 : static nscoord
198 : CalcLength(nsPresContext* aPresContext,
199 : nsStyleContext* aStyleContext,
200 : const nsCSSValue& aCSSValue);
201 :
202 : static bool
203 : ParseNamedSpaceValue(nsIFrame* aMathMLmstyleFrame,
204 : nsString& aString,
205 : nsCSSValue& aCSSValue);
206 :
207 : static eMathMLFrameType
208 0 : GetMathMLFrameTypeFor(nsIFrame* aFrame)
209 : {
210 0 : if (aFrame->IsFrameOfType(nsIFrame::eMathML)) {
211 0 : nsIMathMLFrame* mathMLFrame = do_QueryFrame(aFrame);
212 0 : if (mathMLFrame)
213 0 : return mathMLFrame->GetMathMLFrameType();
214 : }
215 0 : return eMathMLFrameType_UNKNOWN;
216 : }
217 :
218 : // estimate of the italic correction
219 : static void
220 0 : GetItalicCorrection(nsBoundingMetrics& aBoundingMetrics,
221 : nscoord& aItalicCorrection)
222 : {
223 0 : aItalicCorrection = aBoundingMetrics.rightBearing - aBoundingMetrics.width;
224 0 : if (0 > aItalicCorrection) {
225 0 : aItalicCorrection = 0;
226 : }
227 0 : }
228 :
229 : static void
230 0 : GetItalicCorrection(nsBoundingMetrics& aBoundingMetrics,
231 : nscoord& aLeftItalicCorrection,
232 : nscoord& aRightItalicCorrection)
233 : {
234 0 : aRightItalicCorrection = aBoundingMetrics.rightBearing - aBoundingMetrics.width;
235 0 : if (0 > aRightItalicCorrection) {
236 0 : aRightItalicCorrection = 0;
237 : }
238 0 : aLeftItalicCorrection = -aBoundingMetrics.leftBearing;
239 0 : if (0 > aLeftItalicCorrection) {
240 0 : aLeftItalicCorrection = 0;
241 : }
242 0 : }
243 :
244 : // helper methods for getting sup/subdrop's from a child
245 : static void
246 0 : GetSubDropFromChild(nsIFrame* aChild,
247 : nscoord& aSubDrop)
248 : {
249 0 : nsRefPtr<nsFontMetrics> fm;
250 0 : nsLayoutUtils::GetFontMetricsForFrame(aChild, getter_AddRefs(fm));
251 0 : GetSubDrop(fm, aSubDrop);
252 0 : }
253 :
254 : static void
255 0 : GetSupDropFromChild(nsIFrame* aChild,
256 : nscoord& aSupDrop)
257 : {
258 0 : nsRefPtr<nsFontMetrics> fm;
259 0 : nsLayoutUtils::GetFontMetricsForFrame(aChild, getter_AddRefs(fm));
260 0 : GetSupDrop(fm, aSupDrop);
261 0 : }
262 :
263 : static void
264 : GetSkewCorrectionFromChild(nsIFrame* aChild,
265 : nscoord& aSkewCorrection)
266 : {
267 : // default is 0
268 : // individual classes should over-ride this method if necessary
269 : aSkewCorrection = 0;
270 : }
271 :
272 : // 2 levels of subscript shifts
273 : static void
274 0 : GetSubScriptShifts(nsFontMetrics* fm,
275 : nscoord& aSubScriptShift1,
276 : nscoord& aSubScriptShift2)
277 : {
278 0 : nscoord xHeight = fm->XHeight();
279 0 : aSubScriptShift1 = NSToCoordRound(150.000f/430.556f * xHeight);
280 0 : aSubScriptShift2 = NSToCoordRound(247.217f/430.556f * xHeight);
281 0 : }
282 :
283 : // 3 levels of superscript shifts
284 : static void
285 0 : GetSupScriptShifts(nsFontMetrics* fm,
286 : nscoord& aSupScriptShift1,
287 : nscoord& aSupScriptShift2,
288 : nscoord& aSupScriptShift3)
289 : {
290 0 : nscoord xHeight = fm->XHeight();
291 0 : aSupScriptShift1 = NSToCoordRound(412.892f/430.556f * xHeight);
292 0 : aSupScriptShift2 = NSToCoordRound(362.892f/430.556f * xHeight);
293 0 : aSupScriptShift3 = NSToCoordRound(288.889f/430.556f * xHeight);
294 0 : }
295 :
296 : // these are TeX specific params not found in ordinary fonts
297 :
298 : static void
299 0 : GetSubDrop(nsFontMetrics* fm,
300 : nscoord& aSubDrop)
301 : {
302 0 : nscoord xHeight = fm->XHeight();
303 0 : aSubDrop = NSToCoordRound(50.000f/430.556f * xHeight);
304 0 : }
305 :
306 : static void
307 0 : GetSupDrop(nsFontMetrics* fm,
308 : nscoord& aSupDrop)
309 : {
310 0 : nscoord xHeight = fm->XHeight();
311 0 : aSupDrop = NSToCoordRound(386.108f/430.556f * xHeight);
312 0 : }
313 :
314 : static void
315 0 : GetNumeratorShifts(nsFontMetrics* fm,
316 : nscoord& numShift1,
317 : nscoord& numShift2,
318 : nscoord& numShift3)
319 : {
320 0 : nscoord xHeight = fm->XHeight();
321 0 : numShift1 = NSToCoordRound(676.508f/430.556f * xHeight);
322 0 : numShift2 = NSToCoordRound(393.732f/430.556f * xHeight);
323 0 : numShift3 = NSToCoordRound(443.731f/430.556f * xHeight);
324 0 : }
325 :
326 : static void
327 0 : GetDenominatorShifts(nsFontMetrics* fm,
328 : nscoord& denShift1,
329 : nscoord& denShift2)
330 : {
331 0 : nscoord xHeight = fm->XHeight();
332 0 : denShift1 = NSToCoordRound(685.951f/430.556f * xHeight);
333 0 : denShift2 = NSToCoordRound(344.841f/430.556f * xHeight);
334 0 : }
335 :
336 : static void
337 0 : GetEmHeight(nsFontMetrics* fm,
338 : nscoord& emHeight)
339 : {
340 : #if 0
341 : // should switch to this API in order to scale with changes of TextZoom
342 : emHeight = fm->EmHeight();
343 : #else
344 0 : emHeight = NSToCoordRound(float(fm->Font().size));
345 : #endif
346 0 : }
347 :
348 : static void
349 0 : GetAxisHeight (nsFontMetrics* fm,
350 : nscoord& axisHeight)
351 : {
352 0 : axisHeight = NSToCoordRound(250.000f/430.556f * fm->XHeight());
353 0 : }
354 :
355 : static void
356 0 : GetBigOpSpacings(nsFontMetrics* fm,
357 : nscoord& bigOpSpacing1,
358 : nscoord& bigOpSpacing2,
359 : nscoord& bigOpSpacing3,
360 : nscoord& bigOpSpacing4,
361 : nscoord& bigOpSpacing5)
362 : {
363 0 : nscoord xHeight = fm->XHeight();
364 0 : bigOpSpacing1 = NSToCoordRound(111.111f/430.556f * xHeight);
365 0 : bigOpSpacing2 = NSToCoordRound(166.667f/430.556f * xHeight);
366 0 : bigOpSpacing3 = NSToCoordRound(200.000f/430.556f * xHeight);
367 0 : bigOpSpacing4 = NSToCoordRound(600.000f/430.556f * xHeight);
368 0 : bigOpSpacing5 = NSToCoordRound(100.000f/430.556f * xHeight);
369 0 : }
370 :
371 : static void
372 0 : GetRuleThickness(nsFontMetrics* fm,
373 : nscoord& ruleThickness)
374 : {
375 0 : nscoord xHeight = fm->XHeight();
376 0 : ruleThickness = NSToCoordRound(40.000f/430.556f * xHeight);
377 0 : }
378 :
379 : // Some parameters are not accurately obtained using the x-height.
380 : // Here are some slower variants to obtain the desired metrics
381 : // by actually measuring some characters
382 : static void
383 : GetRuleThickness(nsRenderingContext& aRenderingContext,
384 : nsFontMetrics* aFontMetrics,
385 : nscoord& aRuleThickness);
386 :
387 : static void
388 : GetAxisHeight(nsRenderingContext& aRenderingContext,
389 : nsFontMetrics* aFontMetrics,
390 : nscoord& aAxisHeight);
391 :
392 : protected:
393 : #if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
394 : nsresult DisplayBoundingMetrics(nsDisplayListBuilder* aBuilder,
395 : nsIFrame* aFrame, const nsPoint& aPt,
396 : const nsBoundingMetrics& aMetrics,
397 : const nsDisplayListSet& aLists);
398 : #endif
399 :
400 : /**
401 : * Display a solid rectangle in the frame's text color. Used for drawing
402 : * fraction separators and root/sqrt overbars.
403 : */
404 : nsresult DisplayBar(nsDisplayListBuilder* aBuilder,
405 : nsIFrame* aFrame, const nsRect& aRect,
406 : const nsDisplayListSet& aLists);
407 :
408 : // information about the presentation policy of the frame
409 : nsPresentationData mPresentationData;
410 :
411 : // information about a container that is an embellished operator
412 : nsEmbellishData mEmbellishData;
413 :
414 : // Metrics that _exactly_ enclose the text of the frame
415 : nsBoundingMetrics mBoundingMetrics;
416 :
417 : // Reference point of the frame: mReference.y is the baseline
418 : nsPoint mReference;
419 : };
420 :
421 : #endif /* nsMathMLFrame_h___ */
|