mirror of
https://github.com/mozilla-firefox/firefox.git
synced 2026-06-14 11:03:31 -05:00
Also adds WPT reftests to validate alignment behavior in horizontal and vertical writing modes with the different `alignment-baseline` values. Additionally: - The `alignment-baseline: middle` tests have failing expectations. This is because the existing implementation does not match the css-inline-3 definition (which the new WPTs follow). See Bug 2030203. - The WidthTest-Regular.otf support font was updated to remove its unusual ideographic-under baseline value, which affected its synthesized central baseline. With the new support for `alignment-baseline: central`, this broke a number of `text-combine-upright-compression-*` WPT reftests. The non-centered baseline values were removed from this test using FontForge, so that the synthesized central baseline matched the expectation of the test references. Differential Revision: https://phabricator.services.mozilla.com/D292136
123 lines
5.0 KiB
C++
123 lines
5.0 KiB
C++
/* 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 "Baseline.h"
|
|
|
|
#include "nsIFrame.h"
|
|
|
|
namespace mozilla {
|
|
|
|
static inline nscoord ComputeBStartOffset(WritingMode aWM,
|
|
BaselineSharingGroup aGroup,
|
|
nscoord aBSize,
|
|
const LogicalMargin& aMargin) {
|
|
return aGroup == BaselineSharingGroup::First ? -aMargin.BStart(aWM)
|
|
: aBSize + aMargin.BStart(aWM);
|
|
}
|
|
|
|
static inline nscoord ComputeBEndOffset(WritingMode aWM,
|
|
BaselineSharingGroup aGroup,
|
|
nscoord aBSize,
|
|
const LogicalMargin& aMargin) {
|
|
return aGroup == BaselineSharingGroup::First ? aBSize + aMargin.BEnd(aWM)
|
|
: -aMargin.BEnd(aWM);
|
|
}
|
|
|
|
enum class BoxType { Margin, Border, Padding, Content };
|
|
|
|
template <BoxType aType>
|
|
static nscoord SynthesizeBOffsetFromInnerBox(const nsIFrame* aFrame,
|
|
WritingMode aWM,
|
|
BaselineSharingGroup aGroup) {
|
|
WritingMode wm = aFrame->GetWritingMode();
|
|
MOZ_ASSERT_IF(aType != BoxType::Border, !aWM.IsOrthogonalTo(wm));
|
|
|
|
const LogicalMargin bp = ([&] {
|
|
switch (aType) {
|
|
case BoxType::Margin:
|
|
// Bug 2034085 - This is not currently applying the logical skip sides
|
|
// to the margin box, unlike the other boxes below. This may be
|
|
// resulting in incorrect offset calculations if the box is fragmented.
|
|
return aFrame->GetLogicalUsedMargin(aWM);
|
|
case BoxType::Border:
|
|
return LogicalMargin(aWM);
|
|
case BoxType::Padding:
|
|
return LogicalMargin(aWM) -
|
|
aFrame->GetLogicalUsedBorder(aWM)
|
|
.ApplySkipSides(aFrame->GetLogicalSkipSides())
|
|
.ConvertTo(aWM, wm);
|
|
case BoxType::Content:
|
|
return LogicalMargin(aWM) -
|
|
aFrame->GetLogicalUsedBorderAndPadding(wm)
|
|
.ApplySkipSides(aFrame->GetLogicalSkipSides())
|
|
.ConvertTo(aWM, wm);
|
|
}
|
|
MOZ_CRASH();
|
|
})();
|
|
|
|
StyleAlignmentBaseline baseline = aFrame->AlignmentBaseline();
|
|
if (baseline == StyleAlignmentBaseline::Baseline) {
|
|
baseline = aWM.IsCentralBaseline() ? StyleAlignmentBaseline::Central
|
|
: StyleAlignmentBaseline::Alphabetic;
|
|
}
|
|
|
|
BaselineSharingGroup group = aGroup;
|
|
if (aWM.IsLineInverted()) {
|
|
group = GetOppositeBaselineSharingGroup(aGroup);
|
|
}
|
|
|
|
// Synthesize the inline baseline for an atomic inline from its margin box.
|
|
// See: https://www.w3.org/TR/css-inline-3/#baseline-synthesis-box
|
|
switch (baseline) {
|
|
case StyleAlignmentBaseline::Baseline:
|
|
MOZ_ASSERT_UNREACHABLE("Baseline is already handled");
|
|
[[fallthrough]];
|
|
|
|
default:
|
|
case StyleAlignmentBaseline::Alphabetic:
|
|
case StyleAlignmentBaseline::Ideographic:
|
|
case StyleAlignmentBaseline::TextBottom:
|
|
return ComputeBEndOffset(aWM, group, aFrame->BSize(aWM), bp);
|
|
|
|
case StyleAlignmentBaseline::Central:
|
|
case StyleAlignmentBaseline::Mathematical:
|
|
case StyleAlignmentBaseline::Middle: {
|
|
nscoord boxBSize = aFrame->BSize(aWM) + bp.BStartEnd(aWM);
|
|
nscoord halfBoxBSize = (boxBSize / 2) + (boxBSize % 2);
|
|
return aWM.IsLineInverted() ? -bp.BEnd(aWM) + halfBoxBSize
|
|
: -bp.BStart(aWM) + halfBoxBSize;
|
|
}
|
|
|
|
case StyleAlignmentBaseline::Hanging:
|
|
case StyleAlignmentBaseline::TextTop:
|
|
return ComputeBStartOffset(aWM, group, aFrame->BSize(aWM), bp);
|
|
}
|
|
}
|
|
|
|
nscoord Baseline::SynthesizeBOffsetFromContentBox(const nsIFrame* aFrame,
|
|
WritingMode aWM,
|
|
BaselineSharingGroup aGroup) {
|
|
return SynthesizeBOffsetFromInnerBox<BoxType::Content>(aFrame, aWM, aGroup);
|
|
}
|
|
|
|
nscoord Baseline::SynthesizeBOffsetFromPaddingBox(const nsIFrame* aFrame,
|
|
WritingMode aWM,
|
|
BaselineSharingGroup aGroup) {
|
|
return SynthesizeBOffsetFromInnerBox<BoxType::Padding>(aFrame, aWM, aGroup);
|
|
}
|
|
|
|
nscoord Baseline::SynthesizeBOffsetFromBorderBox(const nsIFrame* aFrame,
|
|
WritingMode aWM,
|
|
BaselineSharingGroup aGroup) {
|
|
return SynthesizeBOffsetFromInnerBox<BoxType::Border>(aFrame, aWM, aGroup);
|
|
}
|
|
|
|
nscoord Baseline::SynthesizeBOffsetFromMarginBox(const nsIFrame* aFrame,
|
|
WritingMode aWM,
|
|
BaselineSharingGroup aGroup) {
|
|
return SynthesizeBOffsetFromInnerBox<BoxType::Margin>(aFrame, aWM, aGroup);
|
|
}
|
|
|
|
} // namespace mozilla
|