Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / layout / mathml / base / src / nsMathMLmsubFrame.cpp
blobbe18506156653b003b002bfc4c7c095f178a16a3
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
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/
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.
15 * The Original Code is Mozilla MathML Project.
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.
22 * Contributor(s):
23 * Roger B. Sidje <rbs@maths.uq.edu.au>
24 * David J. Fiddes <D.J.Fiddes@hw.ac.uk>
25 * Shyjan Mahamud <mahamud@cs.cmu.edu> (added TeX rendering rules)
27 * Alternatively, the contents of this file may be used under the terms of
28 * either of the GNU General Public License Version 2 or later (the "GPL"),
29 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
42 #include "nsCOMPtr.h"
43 #include "nsFrame.h"
44 #include "nsPresContext.h"
45 #include "nsStyleContext.h"
46 #include "nsStyleConsts.h"
47 #include "nsIRenderingContext.h"
48 #include "nsIFontMetrics.h"
50 #include "nsMathMLmsubFrame.h"
53 // <msub> -- attach a subscript to a base - implementation
56 nsIFrame*
57 NS_NewMathMLmsubFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
59 return new (aPresShell) nsMathMLmsubFrame(aContext);
62 nsMathMLmsubFrame::~nsMathMLmsubFrame()
66 NS_IMETHODIMP
67 nsMathMLmsubFrame::TransmitAutomaticData()
69 // if our base is an embellished operator, let its state bubble to us
70 mPresentationData.baseFrame = mFrames.FirstChild();
71 GetEmbellishDataFrom(mPresentationData.baseFrame, mEmbellishData);
73 // 1. The REC says:
74 // The <msub> element increments scriptlevel by 1, and sets displaystyle to
75 // "false", within subscript, but leaves both attributes unchanged within base.
76 // 2. The TeXbook (Ch 17. p.141) says the subscript is compressed
77 UpdatePresentationDataFromChildAt(1, -1,
78 ~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED,
79 NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED);
81 return NS_OK;
84 /* virtual */ nsresult
85 nsMathMLmsubFrame::Place (nsIRenderingContext& aRenderingContext,
86 PRBool aPlaceOrigin,
87 nsHTMLReflowMetrics& aDesiredSize)
89 // extra spacing after sup/subscript
90 nscoord scriptSpace = PresContext()->PointsToAppUnits(0.5f); // 0.5pt as in plain TeX
92 // check if the subscriptshift attribute is there
93 nscoord subScriptShift = 0;
94 nsAutoString value;
95 GetAttribute(mContent, mPresentationData.mstyle,
96 nsGkAtoms::subscriptshift_, value);
97 if (!value.IsEmpty()) {
98 nsCSSValue cssValue;
99 if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) {
100 subScriptShift = CalcLength(PresContext(), mStyleContext, cssValue);
104 return nsMathMLmsubFrame::PlaceSubScript(PresContext(),
105 aRenderingContext,
106 aPlaceOrigin,
107 aDesiredSize,
108 this,
109 subScriptShift,
110 scriptSpace);
113 // exported routine that both munder and msub share.
114 // munder uses this when movablelimits is set.
115 nsresult
116 nsMathMLmsubFrame::PlaceSubScript (nsPresContext* aPresContext,
117 nsIRenderingContext& aRenderingContext,
118 PRBool aPlaceOrigin,
119 nsHTMLReflowMetrics& aDesiredSize,
120 nsMathMLContainerFrame* aFrame,
121 nscoord aUserSubScriptShift,
122 nscoord aScriptSpace)
124 // force the scriptSpace to be atleast 1 pixel
125 aScriptSpace = PR_MAX(nsPresContext::CSSPixelsToAppUnits(1), aScriptSpace);
127 ////////////////////////////////////
128 // Get the children's desired sizes
130 nsBoundingMetrics bmBase, bmSubScript;
131 nsHTMLReflowMetrics baseSize;
132 nsHTMLReflowMetrics subScriptSize;
133 nsIFrame* baseFrame = aFrame->GetFirstChild(nsnull);
134 nsIFrame* subScriptFrame = nsnull;
135 if (baseFrame)
136 subScriptFrame = baseFrame->GetNextSibling();
137 if (!baseFrame || !subScriptFrame || subScriptFrame->GetNextSibling()) {
138 // report an error, encourage people to get their markups in order
139 return aFrame->ReflowError(aRenderingContext, aDesiredSize);
141 GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
142 GetReflowAndBoundingMetricsFor(subScriptFrame, subScriptSize, bmSubScript);
144 // get the subdrop from the subscript font
145 nscoord subDrop;
146 GetSubDropFromChild(subScriptFrame, subDrop);
147 // parameter v, Rule 18a, App. G, TeXbook
148 nscoord minSubScriptShift = bmBase.descent + subDrop;
150 //////////////////
151 // Place Children
153 // get min subscript shift limit from x-height
154 // = h(x) - 4/5 * sigma_5, Rule 18b, App. G, TeXbook
155 nscoord xHeight = 0;
156 nsCOMPtr<nsIFontMetrics> fm =
157 aPresContext->GetMetricsFor(baseFrame->GetStyleFont()->mFont);
159 fm->GetXHeight (xHeight);
160 nscoord minShiftFromXHeight = (nscoord)
161 (bmSubScript.ascent - (4.0f/5.0f) * xHeight);
163 // subScriptShift
164 // = minimum amount to shift the subscript down set by user or from the font
165 // = sub1 in TeX
166 // = subscriptshift attribute * x-height
167 nscoord subScriptShift, dummy;
168 // get subScriptShift default from font
169 GetSubScriptShifts (fm, subScriptShift, dummy);
171 subScriptShift =
172 PR_MAX(subScriptShift, aUserSubScriptShift);
174 // get actual subscriptshift to be used
175 // Rule 18b, App. G, TeXbook
176 nscoord actualSubScriptShift =
177 PR_MAX(minSubScriptShift,PR_MAX(subScriptShift,minShiftFromXHeight));
178 // get bounding box for base + subscript
179 nsBoundingMetrics boundingMetrics;
180 boundingMetrics.ascent =
181 PR_MAX(bmBase.ascent, bmSubScript.ascent - actualSubScriptShift);
182 boundingMetrics.descent =
183 PR_MAX(bmBase.descent, bmSubScript.descent + actualSubScriptShift);
185 // add aScriptSpace to the subscript's width
186 boundingMetrics.width = bmBase.width + bmSubScript.width + aScriptSpace;
187 boundingMetrics.leftBearing = bmBase.leftBearing;
188 boundingMetrics.rightBearing = PR_MAX(bmBase.rightBearing, bmBase.width +
189 PR_MAX(bmSubScript.width + aScriptSpace, bmSubScript.rightBearing));
190 aFrame->SetBoundingMetrics (boundingMetrics);
192 // reflow metrics
193 aDesiredSize.ascent =
194 PR_MAX(baseSize.ascent, subScriptSize.ascent - actualSubScriptShift);
195 aDesiredSize.height = aDesiredSize.ascent +
196 PR_MAX(baseSize.height - baseSize.ascent,
197 subScriptSize.height - subScriptSize.ascent + actualSubScriptShift);
198 aDesiredSize.width = boundingMetrics.width;
199 aDesiredSize.mBoundingMetrics = boundingMetrics;
201 aFrame->SetReference(nsPoint(0, aDesiredSize.ascent));
203 if (aPlaceOrigin) {
204 nscoord dx, dy;
205 // now place the base ...
206 dx = 0; dy = aDesiredSize.ascent - baseSize.ascent;
207 FinishReflowChild (baseFrame, aPresContext, nsnull, baseSize, dx, dy, 0);
208 // ... and subscript
209 dx = bmBase.width;
210 dy = aDesiredSize.ascent - (subScriptSize.ascent - actualSubScriptShift);
211 FinishReflowChild (subScriptFrame, aPresContext, nsnull, subScriptSize, dx, dy, 0);
214 return NS_OK;