mirror of
https://github.com/HeyPuter/firefox.git
synced 2026-11-13 20:14:57 -10:00
MathML classes has a few Place*() methods used for layout and intrinsic size calculation. These methods have a parameter "aPlaceOrigin" indicating whether the children and other painted objects should have their final positions set, or if the method is only called for measuring. This parameter is typically set to false when doing intrinsic size calculation or when performing some non-final measurement for operator stretching. For intrinsic size calculation, it is generally enough to perform placement with aPlaceOrigin=false and ignoring the vertical metrics. Some Place*() methods also have a parameter "aWidthOnly" for special handling. For example, msqrt stretches a radical symbol vertically to match the height of the content but when doing intrinsic size calculation this is approximated to nsMathMLChar::GetMaxWidth() instead. When we implement border/padding/margin we should also be able to choose between using IntrinsicISizeOffsets() or GetUsed*() methods. Finally, some Place*() methods initially call a place routing of a parent class before further tweaking the layout. For example, msqrt uses mrow layout on children and adds some radical symbol on top of them. When we implement border/padding, we should make sure we don't add the border/padding before the final result. In order to handle all these placement behaviors, a new EnumSet is introduced. This commit does not change behavior. Handling of padding, border and margin will be handled in follow-up patches. Differential Revision: https://phabricator.services.mozilla.com/D216669
124 lines
4.1 KiB
C++
124 lines
4.1 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* 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/. */
|
|
|
|
#include "nsMathMLmspaceFrame.h"
|
|
|
|
#include "mozilla/dom/MathMLElement.h"
|
|
#include "mozilla/PresShell.h"
|
|
#include "mozilla/gfx/2D.h"
|
|
#include "nsLayoutUtils.h"
|
|
#include <algorithm>
|
|
|
|
using namespace mozilla;
|
|
|
|
//
|
|
// <mspace> -- space - implementation
|
|
//
|
|
|
|
nsIFrame* NS_NewMathMLmspaceFrame(PresShell* aPresShell,
|
|
ComputedStyle* aStyle) {
|
|
return new (aPresShell)
|
|
nsMathMLmspaceFrame(aStyle, aPresShell->GetPresContext());
|
|
}
|
|
|
|
NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmspaceFrame)
|
|
|
|
nsMathMLmspaceFrame::~nsMathMLmspaceFrame() = default;
|
|
|
|
void nsMathMLmspaceFrame::ProcessAttributes(nsPresContext* aPresContext) {
|
|
nsAutoString value;
|
|
float fontSizeInflation = nsLayoutUtils::FontSizeInflationFor(this);
|
|
|
|
// width
|
|
//
|
|
// "Specifies the desired width of the space."
|
|
//
|
|
// values: length
|
|
// default: 0em
|
|
//
|
|
// The default value is "0em", so unitless values can be ignored.
|
|
// <mspace/> is listed among MathML elements allowing negative spacing and
|
|
// the MathML test suite contains "Presentation/TokenElements/mspace/mspace2"
|
|
// as an example. Hence we allow negative values.
|
|
//
|
|
mWidth = 0;
|
|
mContent->AsElement()->GetAttr(nsGkAtoms::width, value);
|
|
if (!value.IsEmpty()) {
|
|
ParseNumericValue(value, &mWidth, dom::MathMLElement::PARSE_ALLOW_NEGATIVE,
|
|
aPresContext, mComputedStyle, fontSizeInflation);
|
|
}
|
|
|
|
// height
|
|
//
|
|
// "Specifies the desired height (above the baseline) of the space."
|
|
//
|
|
// values: length
|
|
// default: 0ex
|
|
//
|
|
// The default value is "0ex", so unitless values can be ignored.
|
|
// We do not allow negative values. See bug 716349.
|
|
//
|
|
mHeight = 0;
|
|
mContent->AsElement()->GetAttr(nsGkAtoms::height, value);
|
|
if (!value.IsEmpty()) {
|
|
ParseNumericValue(value, &mHeight, 0, aPresContext, mComputedStyle,
|
|
fontSizeInflation);
|
|
}
|
|
|
|
// depth
|
|
//
|
|
// "Specifies the desired depth (below the baseline) of the space."
|
|
//
|
|
// values: length
|
|
// default: 0ex
|
|
//
|
|
// The default value is "0ex", so unitless values can be ignored.
|
|
// We do not allow negative values. See bug 716349.
|
|
//
|
|
mDepth = 0;
|
|
mContent->AsElement()->GetAttr(nsGkAtoms::depth_, value);
|
|
if (!value.IsEmpty()) {
|
|
ParseNumericValue(value, &mDepth, 0, aPresContext, mComputedStyle,
|
|
fontSizeInflation);
|
|
}
|
|
}
|
|
|
|
void nsMathMLmspaceFrame::Reflow(nsPresContext* aPresContext,
|
|
ReflowOutput& aDesiredSize,
|
|
const ReflowInput& aReflowInput,
|
|
nsReflowStatus& aStatus) {
|
|
MarkInReflow();
|
|
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
|
|
|
|
ProcessAttributes(aPresContext);
|
|
|
|
const auto& borderPadding = GetUsedBorderAndPadding();
|
|
mBoundingMetrics = nsBoundingMetrics();
|
|
mBoundingMetrics.width = mWidth + borderPadding.LeftRight();
|
|
mBoundingMetrics.ascent = mHeight + borderPadding.top;
|
|
mBoundingMetrics.descent = mDepth + borderPadding.bottom;
|
|
mBoundingMetrics.leftBearing = 0;
|
|
mBoundingMetrics.rightBearing = mBoundingMetrics.width;
|
|
|
|
aDesiredSize.SetBlockStartAscent(mBoundingMetrics.ascent);
|
|
aDesiredSize.Width() = std::max(0, mBoundingMetrics.width);
|
|
aDesiredSize.Height() = mBoundingMetrics.ascent + mBoundingMetrics.descent;
|
|
// Also return our bounding metrics
|
|
aDesiredSize.mBoundingMetrics = mBoundingMetrics;
|
|
}
|
|
|
|
/* virtual */
|
|
nsresult nsMathMLmspaceFrame::MeasureForWidth(DrawTarget* aDrawTarget,
|
|
ReflowOutput& aDesiredSize) {
|
|
ProcessAttributes(PresContext());
|
|
mBoundingMetrics = nsBoundingMetrics();
|
|
auto offsets = IntrinsicISizeOffsets();
|
|
mBoundingMetrics.width = mWidth + offsets.BorderPadding();
|
|
aDesiredSize.Width() = std::max(0, mBoundingMetrics.width);
|
|
aDesiredSize.mBoundingMetrics = mBoundingMetrics;
|
|
return NS_OK;
|
|
}
|