2007-06-12 06:10:23 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2012-05-21 11:12:37 +00:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
1999-09-21 02:12:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
#include "nsMathMLmpaddedFrame.h"
|
2013-08-30 21:37:12 +00:00
|
|
|
#include "nsMathMLElement.h"
|
2013-10-07 23:15:59 +00:00
|
|
|
#include "mozilla/gfx/2D.h"
|
2013-01-15 12:22:03 +00:00
|
|
|
#include <algorithm>
|
1999-09-21 02:12:01 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// <mpadded> -- adjust space around content - implementation
|
|
|
|
//
|
|
|
|
|
2000-01-27 12:35:30 +00:00
|
|
|
#define NS_MATHML_SIGN_INVALID -1 // if the attribute is not there
|
|
|
|
#define NS_MATHML_SIGN_UNSPECIFIED 0
|
|
|
|
#define NS_MATHML_SIGN_MINUS 1
|
|
|
|
#define NS_MATHML_SIGN_PLUS 2
|
|
|
|
|
|
|
|
#define NS_MATHML_PSEUDO_UNIT_UNSPECIFIED 0
|
|
|
|
#define NS_MATHML_PSEUDO_UNIT_ITSELF 1 // special
|
|
|
|
#define NS_MATHML_PSEUDO_UNIT_WIDTH 2
|
|
|
|
#define NS_MATHML_PSEUDO_UNIT_HEIGHT 3
|
|
|
|
#define NS_MATHML_PSEUDO_UNIT_DEPTH 4
|
2011-07-03 07:53:17 +00:00
|
|
|
#define NS_MATHML_PSEUDO_UNIT_NAMEDSPACE 5
|
2000-01-27 12:35:30 +00:00
|
|
|
|
2005-11-11 02:36:29 +00:00
|
|
|
nsIFrame*
|
2006-03-26 21:30:36 +00:00
|
|
|
NS_NewMathMLmpaddedFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
|
1999-09-21 02:12:01 +00:00
|
|
|
{
|
2006-03-26 21:30:36 +00:00
|
|
|
return new (aPresShell) nsMathMLmpaddedFrame(aContext);
|
1999-09-21 02:12:01 +00:00
|
|
|
}
|
|
|
|
|
2009-09-12 16:49:24 +00:00
|
|
|
NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmpaddedFrame)
|
|
|
|
|
1999-09-21 02:12:01 +00:00
|
|
|
nsMathMLmpaddedFrame::~nsMathMLmpaddedFrame()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2005-02-07 01:57:50 +00:00
|
|
|
nsMathMLmpaddedFrame::InheritAutomaticData(nsIFrame* aParent)
|
1999-09-21 02:12:01 +00:00
|
|
|
{
|
2002-02-02 05:43:03 +00:00
|
|
|
// let the base class get the default from our parent
|
2005-02-07 01:57:50 +00:00
|
|
|
nsMathMLContainerFrame::InheritAutomaticData(aParent);
|
1999-09-21 02:12:01 +00:00
|
|
|
|
2002-02-07 04:38:08 +00:00
|
|
|
mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2005-02-07 01:57:50 +00:00
|
|
|
nsMathMLmpaddedFrame::ProcessAttributes()
|
2002-02-07 04:38:08 +00:00
|
|
|
{
|
2000-01-27 12:35:30 +00:00
|
|
|
/*
|
|
|
|
parse the attributes
|
|
|
|
|
2011-07-03 07:54:01 +00:00
|
|
|
width = [+|-] unsigned-number (% [pseudo-unit] | pseudo-unit | h-unit | namedspace)
|
|
|
|
height = [+|-] unsigned-number (% [pseudo-unit] | pseudo-unit | v-unit | namedspace)
|
|
|
|
depth = [+|-] unsigned-number (% [pseudo-unit] | pseudo-unit | v-unit | namedspace)
|
|
|
|
lspace = [+|-] unsigned-number (% [pseudo-unit] | pseudo-unit | h-unit | namedspace)
|
|
|
|
voffset= [+|-] unsigned-number (% [pseudo-unit] | pseudo-unit | v-unit | namedspace)
|
2000-01-27 12:35:30 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
nsAutoString value;
|
|
|
|
|
|
|
|
// width
|
|
|
|
mWidthSign = NS_MATHML_SIGN_INVALID;
|
2014-01-15 15:07:06 +00:00
|
|
|
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::width, value);
|
2005-10-28 11:25:24 +00:00
|
|
|
if (!value.IsEmpty()) {
|
2012-12-27 16:12:05 +00:00
|
|
|
if (!ParseAttribute(value, mWidthSign, mWidth, mWidthPseudoUnit)) {
|
|
|
|
ReportParseError(nsGkAtoms::width->GetUTF16String(), value.get());
|
|
|
|
}
|
2000-01-27 12:35:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// height
|
|
|
|
mHeightSign = NS_MATHML_SIGN_INVALID;
|
2014-01-15 15:07:06 +00:00
|
|
|
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::height, value);
|
2005-10-28 11:25:24 +00:00
|
|
|
if (!value.IsEmpty()) {
|
2012-12-27 16:12:05 +00:00
|
|
|
if (!ParseAttribute(value, mHeightSign, mHeight, mHeightPseudoUnit)) {
|
|
|
|
ReportParseError(nsGkAtoms::height->GetUTF16String(), value.get());
|
|
|
|
}
|
2000-01-27 12:35:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// depth
|
|
|
|
mDepthSign = NS_MATHML_SIGN_INVALID;
|
2014-01-15 15:07:06 +00:00
|
|
|
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::depth_, value);
|
2005-10-28 11:25:24 +00:00
|
|
|
if (!value.IsEmpty()) {
|
2012-12-27 16:12:05 +00:00
|
|
|
if (!ParseAttribute(value, mDepthSign, mDepth, mDepthPseudoUnit)) {
|
|
|
|
ReportParseError(nsGkAtoms::depth_->GetUTF16String(), value.get());
|
|
|
|
}
|
2000-01-27 12:35:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// lspace
|
2010-01-05 10:22:31 +00:00
|
|
|
mLeadingSpaceSign = NS_MATHML_SIGN_INVALID;
|
2014-01-15 15:07:06 +00:00
|
|
|
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::lspace_, value);
|
2005-10-28 11:25:24 +00:00
|
|
|
if (!value.IsEmpty()) {
|
2012-12-27 16:12:05 +00:00
|
|
|
if (!ParseAttribute(value, mLeadingSpaceSign, mLeadingSpace,
|
|
|
|
mLeadingSpacePseudoUnit)) {
|
|
|
|
ReportParseError(nsGkAtoms::lspace_->GetUTF16String(), value.get());
|
|
|
|
}
|
2000-01-27 12:35:30 +00:00
|
|
|
}
|
2011-07-03 07:54:01 +00:00
|
|
|
|
|
|
|
// voffset
|
|
|
|
mVerticalOffsetSign = NS_MATHML_SIGN_INVALID;
|
2014-01-15 15:07:06 +00:00
|
|
|
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::voffset_, value);
|
2011-07-03 07:54:01 +00:00
|
|
|
if (!value.IsEmpty()) {
|
2012-12-27 16:12:05 +00:00
|
|
|
if (!ParseAttribute(value, mVerticalOffsetSign, mVerticalOffset,
|
|
|
|
mVerticalOffsetPseudoUnit)) {
|
|
|
|
ReportParseError(nsGkAtoms::voffset_->GetUTF16String(), value.get());
|
|
|
|
}
|
2011-07-03 07:54:01 +00:00
|
|
|
}
|
|
|
|
|
1999-09-21 02:12:01 +00:00
|
|
|
}
|
2000-01-27 12:35:30 +00:00
|
|
|
|
2002-06-14 23:20:03 +00:00
|
|
|
// parse an input string in the following format (see bug 148326 for testcases):
|
|
|
|
// [+|-] unsigned-number (% [pseudo-unit] | pseudo-unit | css-unit | namedspace)
|
2011-09-29 06:19:26 +00:00
|
|
|
bool
|
2000-01-27 12:35:30 +00:00
|
|
|
nsMathMLmpaddedFrame::ParseAttribute(nsString& aString,
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t& aSign,
|
2000-01-27 12:35:30 +00:00
|
|
|
nsCSSValue& aCSSValue,
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t& aPseudoUnit)
|
2000-01-27 12:35:30 +00:00
|
|
|
{
|
|
|
|
aCSSValue.Reset();
|
2002-06-14 23:20:03 +00:00
|
|
|
aSign = NS_MATHML_SIGN_INVALID;
|
|
|
|
aPseudoUnit = NS_MATHML_PSEUDO_UNIT_UNSPECIFIED;
|
2000-01-27 12:35:30 +00:00
|
|
|
aString.CompressWhitespace(); // aString is not a const in this code
|
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t stringLength = aString.Length();
|
2002-06-14 23:20:03 +00:00
|
|
|
if (!stringLength)
|
2011-10-17 14:59:28 +00:00
|
|
|
return false;
|
2000-01-27 12:35:30 +00:00
|
|
|
|
2002-06-14 23:20:03 +00:00
|
|
|
nsAutoString number, unit;
|
2000-01-27 12:35:30 +00:00
|
|
|
|
|
|
|
//////////////////////
|
|
|
|
// see if the sign is there
|
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t i = 0;
|
2000-01-27 12:35:30 +00:00
|
|
|
|
|
|
|
if (aString[0] == '+') {
|
|
|
|
aSign = NS_MATHML_SIGN_PLUS;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
else if (aString[0] == '-') {
|
|
|
|
aSign = NS_MATHML_SIGN_MINUS;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
aSign = NS_MATHML_SIGN_UNSPECIFIED;
|
|
|
|
|
2002-06-14 23:20:03 +00:00
|
|
|
// get the number
|
2011-09-29 06:19:26 +00:00
|
|
|
bool gotDot = false, gotPercent = false;
|
2002-06-14 23:20:03 +00:00
|
|
|
for (; i < stringLength; i++) {
|
2014-01-04 15:02:17 +00:00
|
|
|
char16_t c = aString[i];
|
2002-06-14 23:20:03 +00:00
|
|
|
if (gotDot && c == '.') {
|
|
|
|
// error - two dots encountered
|
|
|
|
aSign = NS_MATHML_SIGN_INVALID;
|
2011-10-17 14:59:28 +00:00
|
|
|
return false;
|
2002-06-14 23:20:03 +00:00
|
|
|
}
|
2000-01-27 12:35:30 +00:00
|
|
|
|
2002-06-14 23:20:03 +00:00
|
|
|
if (c == '.')
|
2011-10-17 14:59:28 +00:00
|
|
|
gotDot = true;
|
2002-06-14 23:20:03 +00:00
|
|
|
else if (!nsCRT::IsAsciiDigit(c)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
number.Append(c);
|
2000-01-27 12:35:30 +00:00
|
|
|
}
|
2002-06-14 23:20:03 +00:00
|
|
|
|
|
|
|
// catch error if we didn't enter the loop above... we could simply initialize
|
|
|
|
// floatValue = 1, to cater for cases such as width="height", but that wouldn't
|
|
|
|
// be in line with the spec which requires an explicit number
|
|
|
|
if (number.IsEmpty()) {
|
2000-01-27 12:35:30 +00:00
|
|
|
aSign = NS_MATHML_SIGN_INVALID;
|
2011-10-17 14:59:28 +00:00
|
|
|
return false;
|
2000-01-27 12:35:30 +00:00
|
|
|
}
|
|
|
|
|
2012-07-27 13:59:29 +00:00
|
|
|
nsresult errorCode;
|
2002-06-14 23:20:03 +00:00
|
|
|
float floatValue = number.ToFloat(&errorCode);
|
2012-08-13 13:49:48 +00:00
|
|
|
if (NS_FAILED(errorCode)) {
|
2002-06-14 23:20:03 +00:00
|
|
|
aSign = NS_MATHML_SIGN_INVALID;
|
2011-10-17 14:59:28 +00:00
|
|
|
return false;
|
2002-06-14 23:20:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// see if this is a percentage-based value
|
|
|
|
if (i < stringLength && aString[i] == '%') {
|
|
|
|
i++;
|
2011-10-17 14:59:28 +00:00
|
|
|
gotPercent = true;
|
2002-06-14 23:20:03 +00:00
|
|
|
}
|
2000-01-27 12:35:30 +00:00
|
|
|
|
2002-06-14 23:20:03 +00:00
|
|
|
// the remainder now should be a css-unit, or a pseudo-unit, or a named-space
|
|
|
|
aString.Right(unit, stringLength - i);
|
|
|
|
|
|
|
|
if (unit.IsEmpty()) {
|
2012-05-15 22:30:14 +00:00
|
|
|
if (gotPercent) {
|
|
|
|
// case ["+"|"-"] unsigned-number "%"
|
2002-06-14 23:20:03 +00:00
|
|
|
aCSSValue.SetPercentValue(floatValue / 100.0f);
|
|
|
|
aPseudoUnit = NS_MATHML_PSEUDO_UNIT_ITSELF;
|
2011-10-17 14:59:28 +00:00
|
|
|
return true;
|
2012-05-15 22:30:14 +00:00
|
|
|
} else {
|
2012-05-28 03:32:51 +00:00
|
|
|
// case ["+"|"-"] unsigned-number
|
|
|
|
// XXXfredw: should we allow non-zero unitless values? See bug 757703.
|
|
|
|
if (!floatValue) {
|
|
|
|
aCSSValue.SetFloatValue(floatValue, eCSSUnit_Number);
|
|
|
|
aPseudoUnit = NS_MATHML_PSEUDO_UNIT_ITSELF;
|
|
|
|
return true;
|
|
|
|
}
|
2002-06-14 23:20:03 +00:00
|
|
|
}
|
2000-01-27 12:35:30 +00:00
|
|
|
}
|
2004-04-30 13:23:43 +00:00
|
|
|
else if (unit.EqualsLiteral("width")) aPseudoUnit = NS_MATHML_PSEUDO_UNIT_WIDTH;
|
|
|
|
else if (unit.EqualsLiteral("height")) aPseudoUnit = NS_MATHML_PSEUDO_UNIT_HEIGHT;
|
|
|
|
else if (unit.EqualsLiteral("depth")) aPseudoUnit = NS_MATHML_PSEUDO_UNIT_DEPTH;
|
2002-06-14 23:20:03 +00:00
|
|
|
else if (!gotPercent) { // percentage can only apply to a pseudo-unit
|
|
|
|
|
|
|
|
// see if the unit is a named-space
|
2012-05-15 22:30:14 +00:00
|
|
|
if (nsMathMLElement::ParseNamedSpaceValue(unit, aCSSValue,
|
|
|
|
nsMathMLElement::
|
|
|
|
PARSE_ALLOW_NEGATIVE)) {
|
2002-06-14 23:20:03 +00:00
|
|
|
// re-scale properly, and we know that the unit of the named-space is 'em'
|
|
|
|
floatValue *= aCSSValue.GetFloatValue();
|
|
|
|
aCSSValue.SetFloatValue(floatValue, eCSSUnit_EM);
|
2000-05-16 13:15:15 +00:00
|
|
|
aPseudoUnit = NS_MATHML_PSEUDO_UNIT_NAMEDSPACE;
|
2011-10-17 14:59:28 +00:00
|
|
|
return true;
|
2000-05-16 13:15:15 +00:00
|
|
|
}
|
|
|
|
|
2002-06-14 23:20:03 +00:00
|
|
|
// see if the input was just a CSS value
|
2012-05-15 22:30:14 +00:00
|
|
|
// We are not supposed to have a unitless, percent, negative or namedspace
|
|
|
|
// value here.
|
2002-06-14 23:20:03 +00:00
|
|
|
number.Append(unit); // leave the sign out if it was there
|
2012-12-27 16:12:05 +00:00
|
|
|
if (nsMathMLElement::ParseNumericValue(number, aCSSValue,
|
|
|
|
nsMathMLElement::
|
|
|
|
PARSE_SUPPRESS_WARNINGS, nullptr))
|
2011-10-17 14:59:28 +00:00
|
|
|
return true;
|
2000-01-27 12:35:30 +00:00
|
|
|
}
|
|
|
|
|
2002-06-14 23:20:03 +00:00
|
|
|
// if we enter here, we have a number that will act as a multiplier on a pseudo-unit
|
|
|
|
if (aPseudoUnit != NS_MATHML_PSEUDO_UNIT_UNSPECIFIED) {
|
|
|
|
if (gotPercent)
|
|
|
|
aCSSValue.SetPercentValue(floatValue / 100.0f);
|
|
|
|
else
|
|
|
|
aCSSValue.SetFloatValue(floatValue, eCSSUnit_Number);
|
|
|
|
|
2011-10-17 14:59:28 +00:00
|
|
|
return true;
|
2000-01-27 12:35:30 +00:00
|
|
|
}
|
|
|
|
|
2002-06-14 23:20:03 +00:00
|
|
|
|
2012-06-25 19:59:42 +00:00
|
|
|
#ifdef DEBUG
|
2002-06-14 23:20:03 +00:00
|
|
|
printf("mpadded: attribute with bad numeric value: %s\n",
|
2006-02-03 14:18:39 +00:00
|
|
|
NS_LossyConvertUTF16toASCII(aString).get());
|
2002-06-14 23:20:03 +00:00
|
|
|
#endif
|
|
|
|
// if we reach here, it means we encounter an unexpected input
|
|
|
|
aSign = NS_MATHML_SIGN_INVALID;
|
2011-10-17 14:59:28 +00:00
|
|
|
return false;
|
2000-01-27 12:35:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-08-22 15:56:38 +00:00
|
|
|
nsMathMLmpaddedFrame::UpdateValue(int32_t aSign,
|
|
|
|
int32_t aPseudoUnit,
|
2008-01-03 04:33:21 +00:00
|
|
|
const nsCSSValue& aCSSValue,
|
2013-11-19 14:08:30 +00:00
|
|
|
const nsHTMLReflowMetrics& aDesiredSize,
|
2008-01-03 04:33:21 +00:00
|
|
|
nscoord& aValueToUpdate) const
|
2000-01-27 12:35:30 +00:00
|
|
|
{
|
|
|
|
nsCSSUnit unit = aCSSValue.GetUnit();
|
2002-06-14 23:20:03 +00:00
|
|
|
if (NS_MATHML_SIGN_INVALID != aSign && eCSSUnit_Null != unit) {
|
2002-02-18 23:16:33 +00:00
|
|
|
nscoord scaler = 0, amount = 0;
|
2000-01-27 12:35:30 +00:00
|
|
|
|
2002-06-14 23:20:03 +00:00
|
|
|
if (eCSSUnit_Percent == unit || eCSSUnit_Number == unit) {
|
|
|
|
switch(aPseudoUnit) {
|
2000-01-27 12:35:30 +00:00
|
|
|
case NS_MATHML_PSEUDO_UNIT_WIDTH:
|
2013-12-27 17:59:52 +00:00
|
|
|
scaler = aDesiredSize.Width();
|
2000-01-27 12:35:30 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_MATHML_PSEUDO_UNIT_HEIGHT:
|
2014-06-11 09:45:31 +00:00
|
|
|
scaler = aDesiredSize.BlockStartAscent();
|
2000-01-27 12:35:30 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_MATHML_PSEUDO_UNIT_DEPTH:
|
2014-06-11 09:45:31 +00:00
|
|
|
scaler = aDesiredSize.Height() - aDesiredSize.BlockStartAscent();
|
2000-01-27 12:35:30 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
// if we ever reach here, it would mean something is wrong
|
2000-03-28 09:38:24 +00:00
|
|
|
// somewhere with the setup and/or the caller
|
2009-08-14 14:09:00 +00:00
|
|
|
NS_ERROR("Unexpected Pseudo Unit");
|
2000-01-27 12:35:30 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (eCSSUnit_Number == unit)
|
2000-03-28 09:38:24 +00:00
|
|
|
amount = NSToCoordRound(float(scaler) * aCSSValue.GetFloatValue());
|
2000-01-27 12:35:30 +00:00
|
|
|
else if (eCSSUnit_Percent == unit)
|
2000-03-28 09:38:24 +00:00
|
|
|
amount = NSToCoordRound(float(scaler) * aCSSValue.GetPercentValue());
|
2000-01-27 12:35:30 +00:00
|
|
|
else
|
2007-12-28 23:04:19 +00:00
|
|
|
amount = CalcLength(PresContext(), mStyleContext, aCSSValue);
|
2000-01-27 12:35:30 +00:00
|
|
|
|
|
|
|
if (NS_MATHML_SIGN_PLUS == aSign)
|
|
|
|
aValueToUpdate += amount;
|
|
|
|
else if (NS_MATHML_SIGN_MINUS == aSign)
|
|
|
|
aValueToUpdate -= amount;
|
|
|
|
else
|
|
|
|
aValueToUpdate = amount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-13 00:47:52 +00:00
|
|
|
void
|
2004-07-31 23:15:21 +00:00
|
|
|
nsMathMLmpaddedFrame::Reflow(nsPresContext* aPresContext,
|
2000-01-27 12:35:30 +00:00
|
|
|
nsHTMLReflowMetrics& aDesiredSize,
|
|
|
|
const nsHTMLReflowState& aReflowState,
|
|
|
|
nsReflowStatus& aStatus)
|
|
|
|
{
|
2005-02-07 01:57:50 +00:00
|
|
|
ProcessAttributes();
|
2000-01-27 12:35:30 +00:00
|
|
|
|
|
|
|
///////////////
|
|
|
|
// Let the base class format our content like an inferred mrow
|
2014-05-13 00:47:52 +00:00
|
|
|
nsMathMLContainerFrame::Reflow(aPresContext, aDesiredSize,
|
|
|
|
aReflowState, aStatus);
|
2002-02-07 04:38:08 +00:00
|
|
|
//NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status");
|
2007-12-28 23:04:19 +00:00
|
|
|
}
|
2000-01-27 12:35:30 +00:00
|
|
|
|
2008-03-18 04:52:48 +00:00
|
|
|
/* virtual */ nsresult
|
2011-04-08 01:04:40 +00:00
|
|
|
nsMathMLmpaddedFrame::Place(nsRenderingContext& aRenderingContext,
|
2011-09-29 06:19:26 +00:00
|
|
|
bool aPlaceOrigin,
|
2007-12-28 23:04:19 +00:00
|
|
|
nsHTMLReflowMetrics& aDesiredSize)
|
|
|
|
{
|
|
|
|
nsresult rv =
|
2011-10-17 14:59:28 +00:00
|
|
|
nsMathMLContainerFrame::Place(aRenderingContext, false, aDesiredSize);
|
2007-12-28 23:04:19 +00:00
|
|
|
if (NS_MATHML_HAS_ERROR(mPresentationData.flags) || NS_FAILED(rv)) {
|
2011-08-24 20:54:30 +00:00
|
|
|
DidReflowChildren(GetFirstPrincipalChild());
|
2007-12-28 23:04:19 +00:00
|
|
|
return rv;
|
|
|
|
}
|
2002-06-14 23:20:03 +00:00
|
|
|
|
2014-06-11 09:45:31 +00:00
|
|
|
nscoord height = aDesiredSize.BlockStartAscent();
|
|
|
|
nscoord depth = aDesiredSize.Height() - aDesiredSize.BlockStartAscent();
|
2010-01-05 10:22:31 +00:00
|
|
|
// The REC says:
|
2008-01-03 04:33:21 +00:00
|
|
|
//
|
2010-01-05 10:22:31 +00:00
|
|
|
// "The lspace attribute ('leading' space) specifies the horizontal location
|
|
|
|
// of the positioning point of the child content with respect to the
|
|
|
|
// positioning point of the mpadded element. By default they coincide, and
|
|
|
|
// therefore absolute values for lspace have the same effect as relative
|
|
|
|
// values."
|
2008-01-03 04:33:21 +00:00
|
|
|
//
|
2010-01-05 10:22:31 +00:00
|
|
|
// "MathML renderers should ensure that, except for the effects of the
|
|
|
|
// attributes, the relative spacing between the contents of the mpadded
|
|
|
|
// element and surrounding MathML elements would not be modified by replacing
|
|
|
|
// an mpadded element with an mrow element with the same content, even if
|
|
|
|
// linebreaking occurs within the mpadded element."
|
|
|
|
//
|
|
|
|
// (http://www.w3.org/TR/MathML/chapter3.html#presm.mpadded)
|
|
|
|
//
|
|
|
|
// "In those discussions, the terms leading and trailing are used to specify
|
|
|
|
// a side of an object when which side to use depends on the directionality;
|
|
|
|
// ie. leading means left in LTR but right in RTL."
|
|
|
|
// (http://www.w3.org/TR/MathML/chapter3.html#presm.bidi.math)
|
2008-01-03 04:33:21 +00:00
|
|
|
nscoord lspace = 0;
|
2010-01-05 10:22:31 +00:00
|
|
|
// In MathML3, "width" will be the bounding box width and "advancewidth" will
|
2008-01-03 04:33:21 +00:00
|
|
|
// refer "to the horizontal distance between the positioning point of the
|
|
|
|
// mpadded and the positioning point for the following content". MathML2
|
|
|
|
// doesn't make the distinction.
|
2013-12-27 17:59:52 +00:00
|
|
|
nscoord width = aDesiredSize.Width();
|
2011-07-03 07:54:25 +00:00
|
|
|
nscoord voffset = 0;
|
2000-01-27 12:35:30 +00:00
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t pseudoUnit;
|
2010-01-05 10:22:31 +00:00
|
|
|
nscoord initialWidth = width;
|
2000-01-27 12:35:30 +00:00
|
|
|
|
|
|
|
// update width
|
|
|
|
pseudoUnit = (mWidthPseudoUnit == NS_MATHML_PSEUDO_UNIT_ITSELF)
|
|
|
|
? NS_MATHML_PSEUDO_UNIT_WIDTH : mWidthPseudoUnit;
|
2007-12-28 23:04:19 +00:00
|
|
|
UpdateValue(mWidthSign, pseudoUnit, mWidth,
|
2013-11-19 14:08:30 +00:00
|
|
|
aDesiredSize, width);
|
2013-01-15 12:22:03 +00:00
|
|
|
width = std::max(0, width);
|
2000-01-27 12:35:30 +00:00
|
|
|
|
2002-06-14 23:20:03 +00:00
|
|
|
// update "height" (this is the ascent in the terminology of the REC)
|
2000-01-27 12:35:30 +00:00
|
|
|
pseudoUnit = (mHeightPseudoUnit == NS_MATHML_PSEUDO_UNIT_ITSELF)
|
|
|
|
? NS_MATHML_PSEUDO_UNIT_HEIGHT : mHeightPseudoUnit;
|
2007-12-28 23:04:19 +00:00
|
|
|
UpdateValue(mHeightSign, pseudoUnit, mHeight,
|
2013-11-19 14:08:30 +00:00
|
|
|
aDesiredSize, height);
|
2013-01-15 12:22:03 +00:00
|
|
|
height = std::max(0, height);
|
2000-01-27 12:35:30 +00:00
|
|
|
|
2002-06-14 23:20:03 +00:00
|
|
|
// update "depth" (this is the descent in the terminology of the REC)
|
2000-01-27 12:35:30 +00:00
|
|
|
pseudoUnit = (mDepthPseudoUnit == NS_MATHML_PSEUDO_UNIT_ITSELF)
|
|
|
|
? NS_MATHML_PSEUDO_UNIT_DEPTH : mDepthPseudoUnit;
|
2007-12-28 23:04:19 +00:00
|
|
|
UpdateValue(mDepthSign, pseudoUnit, mDepth,
|
2013-11-19 14:08:30 +00:00
|
|
|
aDesiredSize, depth);
|
2013-01-15 12:22:03 +00:00
|
|
|
depth = std::max(0, depth);
|
2000-01-27 12:35:30 +00:00
|
|
|
|
2011-07-03 07:53:17 +00:00
|
|
|
// update lspace
|
2010-01-05 10:22:31 +00:00
|
|
|
if (mLeadingSpacePseudoUnit != NS_MATHML_PSEUDO_UNIT_ITSELF) {
|
|
|
|
pseudoUnit = mLeadingSpacePseudoUnit;
|
|
|
|
UpdateValue(mLeadingSpaceSign, pseudoUnit, mLeadingSpace,
|
2013-11-19 14:08:30 +00:00
|
|
|
aDesiredSize, lspace);
|
2011-07-03 07:53:17 +00:00
|
|
|
}
|
2000-01-27 12:35:30 +00:00
|
|
|
|
2011-07-03 07:54:25 +00:00
|
|
|
// update voffset
|
|
|
|
if (mVerticalOffsetPseudoUnit != NS_MATHML_PSEUDO_UNIT_ITSELF) {
|
|
|
|
pseudoUnit = mVerticalOffsetPseudoUnit;
|
|
|
|
UpdateValue(mVerticalOffsetSign, pseudoUnit, mVerticalOffset,
|
2013-11-19 14:08:30 +00:00
|
|
|
aDesiredSize, voffset);
|
2011-07-03 07:54:25 +00:00
|
|
|
}
|
2000-01-27 12:35:30 +00:00
|
|
|
// do the padding now that we have everything
|
2002-06-14 23:20:03 +00:00
|
|
|
// The idea here is to maintain the invariant that <mpadded>...</mpadded> (i.e.,
|
|
|
|
// with no attributes) looks the same as <mrow>...</mrow>. But when there are
|
|
|
|
// attributes, tweak our metrics and move children to achieve the desired visual
|
|
|
|
// effects.
|
2000-01-27 12:35:30 +00:00
|
|
|
|
2013-05-29 23:26:40 +00:00
|
|
|
if ((StyleVisibility()->mDirection ?
|
2010-01-05 10:22:31 +00:00
|
|
|
mWidthSign : mLeadingSpaceSign) != NS_MATHML_SIGN_INVALID) {
|
|
|
|
// there was padding on the left. dismiss the left italic correction now
|
|
|
|
// (so that our parent won't correct us)
|
2000-03-28 09:38:24 +00:00
|
|
|
mBoundingMetrics.leftBearing = 0;
|
|
|
|
}
|
|
|
|
|
2013-05-29 23:26:40 +00:00
|
|
|
if ((StyleVisibility()->mDirection ?
|
2010-01-05 10:22:31 +00:00
|
|
|
mLeadingSpaceSign : mWidthSign) != NS_MATHML_SIGN_INVALID) {
|
|
|
|
// there was padding on the right. dismiss the right italic correction now
|
|
|
|
// (so that our parent won't correct us)
|
2011-07-03 07:54:25 +00:00
|
|
|
mBoundingMetrics.width = width;
|
2002-06-14 23:20:03 +00:00
|
|
|
mBoundingMetrics.rightBearing = mBoundingMetrics.width;
|
2000-03-28 09:38:24 +00:00
|
|
|
}
|
|
|
|
|
2013-05-29 23:26:40 +00:00
|
|
|
nscoord dx = (StyleVisibility()->mDirection ?
|
|
|
|
width - initialWidth - lspace : lspace);
|
2010-01-05 10:22:31 +00:00
|
|
|
|
2014-06-11 09:45:31 +00:00
|
|
|
aDesiredSize.SetBlockStartAscent(height);
|
2013-12-27 17:59:52 +00:00
|
|
|
aDesiredSize.Width() = mBoundingMetrics.width;
|
2014-06-11 09:45:31 +00:00
|
|
|
aDesiredSize.Height() = depth + aDesiredSize.BlockStartAscent();
|
2011-07-03 07:54:25 +00:00
|
|
|
mBoundingMetrics.ascent = height;
|
|
|
|
mBoundingMetrics.descent = depth;
|
2001-02-02 21:29:21 +00:00
|
|
|
aDesiredSize.mBoundingMetrics = mBoundingMetrics;
|
2000-03-28 09:38:24 +00:00
|
|
|
|
2007-12-28 23:04:19 +00:00
|
|
|
mReference.x = 0;
|
2014-06-11 09:45:31 +00:00
|
|
|
mReference.y = aDesiredSize.BlockStartAscent();
|
2002-06-14 23:20:03 +00:00
|
|
|
|
2008-01-03 04:33:21 +00:00
|
|
|
if (aPlaceOrigin) {
|
|
|
|
// Finish reflowing child frames, positioning their origins.
|
2014-06-11 09:45:31 +00:00
|
|
|
PositionRowChildFrames(dx, aDesiredSize.BlockStartAscent() - voffset);
|
2000-01-27 12:35:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2012-11-29 22:52:02 +00:00
|
|
|
|
|
|
|
/* virtual */ nsresult
|
|
|
|
nsMathMLmpaddedFrame::MeasureForWidth(nsRenderingContext& aRenderingContext,
|
|
|
|
nsHTMLReflowMetrics& aDesiredSize)
|
|
|
|
{
|
|
|
|
ProcessAttributes();
|
|
|
|
return Place(aRenderingContext, false, aDesiredSize);
|
|
|
|
}
|