fune/layout/generic/nsRubyTextContainerFrame.cpp
Ting-Yu Lin 514d412f9b Bug 1799732 Part 3 - Convert FrameChildListID to enum class. r=emilio
This patch is first generated by the following script under gecko root folder.

```
#!/bin/bash

function rename() {
    echo "Renaming $1 to $2"
    rg -l "$1" | xargs sed -i -E -e s/"$1"/"$2"/g
}

rename "kPrincipalList" "FrameChildListID::Principal"
rename "kPopupList" "FrameChildListID::Popup"
rename "kCaptionList" "FrameChildListID::Caption"
rename "kColGroupList" "FrameChildListID::ColGroup"
rename "kAbsoluteList" "FrameChildListID::Absolute"
rename "kFixedList" "FrameChildListID::Fixed"
rename "kOverflowList" "FrameChildListID::Overflow"
rename "kOverflowContainersList" "FrameChildListID::OverflowContainers"
rename "kExcessOverflowContainersList" "FrameChildListID::ExcessOverflowContainers"
rename "kOverflowOutOfFlowList" "FrameChildListID::OverflowOutOfFlow"
rename "kFloatList" "FrameChildListID::Float"
rename "kBulletList" "FrameChildListID::Bullet"
rename "kPushedFloatsList" "FrameChildListID::PushedFloats"
rename "kBackdropList" "FrameChildListID::Backdrop"
rename "kNoReflowPrincipalList" "FrameChildListID::NoReflowPrincipal"
```

And then:
1. Manually fix `FrameChildListID` definition in nsFrameList.h.
2. Apply clang-format.

Differential Revision: https://phabricator.services.mozilla.com/D161864
2022-11-12 04:38:53 +00:00

172 lines
6.4 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/. */
/* rendering object for CSS "display: ruby-text-container" */
#include "nsRubyTextContainerFrame.h"
#include "mozilla/ComputedStyle.h"
#include "mozilla/PresShell.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/WritingModes.h"
#include "nsLayoutUtils.h"
#include "nsLineLayout.h"
#include "nsPresContext.h"
using namespace mozilla;
//----------------------------------------------------------------------
// Frame class boilerplate
// =======================
NS_QUERYFRAME_HEAD(nsRubyTextContainerFrame)
NS_QUERYFRAME_ENTRY(nsRubyTextContainerFrame)
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
NS_IMPL_FRAMEARENA_HELPERS(nsRubyTextContainerFrame)
nsContainerFrame* NS_NewRubyTextContainerFrame(PresShell* aPresShell,
ComputedStyle* aStyle) {
return new (aPresShell)
nsRubyTextContainerFrame(aStyle, aPresShell->GetPresContext());
}
//----------------------------------------------------------------------
// nsRubyTextContainerFrame Method Implementations
// ===============================================
#ifdef DEBUG_FRAME_DUMP
nsresult nsRubyTextContainerFrame::GetFrameName(nsAString& aResult) const {
return MakeFrameName(u"RubyTextContainer"_ns, aResult);
}
#endif
/* virtual */
bool nsRubyTextContainerFrame::IsFrameOfType(uint32_t aFlags) const {
if (aFlags & (eSupportsCSSTransforms | eSupportsContainLayoutAndPaint |
eSupportsAspectRatio)) {
return false;
}
return nsContainerFrame::IsFrameOfType(aFlags);
}
/* virtual */
void nsRubyTextContainerFrame::SetInitialChildList(ChildListID aListID,
nsFrameList&& aChildList) {
nsContainerFrame::SetInitialChildList(aListID, std::move(aChildList));
if (aListID == FrameChildListID::Principal) {
UpdateSpanFlag();
}
}
/* virtual */
void nsRubyTextContainerFrame::AppendFrames(ChildListID aListID,
nsFrameList&& aFrameList) {
nsContainerFrame::AppendFrames(aListID, std::move(aFrameList));
UpdateSpanFlag();
}
/* virtual */
void nsRubyTextContainerFrame::InsertFrames(
ChildListID aListID, nsIFrame* aPrevFrame,
const nsLineList::iterator* aPrevFrameLine, nsFrameList&& aFrameList) {
nsContainerFrame::InsertFrames(aListID, aPrevFrame, aPrevFrameLine,
std::move(aFrameList));
UpdateSpanFlag();
}
/* virtual */
void nsRubyTextContainerFrame::RemoveFrame(ChildListID aListID,
nsIFrame* aOldFrame) {
nsContainerFrame::RemoveFrame(aListID, aOldFrame);
UpdateSpanFlag();
}
void nsRubyTextContainerFrame::UpdateSpanFlag() {
bool isSpan = false;
// The continuation checks are safe here because spans never break.
if (!GetPrevContinuation() && !GetNextContinuation()) {
nsIFrame* onlyChild = mFrames.OnlyChild();
if (onlyChild && onlyChild->IsPseudoFrame(GetContent())) {
// Per CSS Ruby spec, if the only child of an rtc frame is
// a pseudo rt frame, it spans all bases in the segment.
isSpan = true;
}
}
if (isSpan) {
AddStateBits(NS_RUBY_TEXT_CONTAINER_IS_SPAN);
} else {
RemoveStateBits(NS_RUBY_TEXT_CONTAINER_IS_SPAN);
}
}
/* virtual */
void nsRubyTextContainerFrame::Reflow(nsPresContext* aPresContext,
ReflowOutput& aDesiredSize,
const ReflowInput& aReflowInput,
nsReflowStatus& aStatus) {
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsRubyTextContainerFrame");
DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
// Although a ruby text container may have continuations, returning
// complete reflow status is still safe, since its parent, ruby frame,
// ignores the status, and continuations of the ruby base container
// will take care of our continuations.
WritingMode rtcWM = GetWritingMode();
nscoord minBCoord = nscoord_MAX;
nscoord maxBCoord = nscoord_MIN;
// The container size is not yet known, so we use a dummy (0, 0) size.
// The block-dir position will be corrected below after containerSize
// is finalized.
const nsSize dummyContainerSize;
for (nsIFrame* child : mFrames) {
MOZ_ASSERT(child->IsRubyTextFrame());
LogicalRect rect = child->GetLogicalRect(rtcWM, dummyContainerSize);
LogicalMargin margin = child->GetLogicalUsedMargin(rtcWM);
nscoord blockStart = rect.BStart(rtcWM) - margin.BStart(rtcWM);
minBCoord = std::min(minBCoord, blockStart);
nscoord blockEnd = rect.BEnd(rtcWM) + margin.BEnd(rtcWM);
maxBCoord = std::max(maxBCoord, blockEnd);
}
if (!mFrames.IsEmpty()) {
if (MOZ_UNLIKELY(minBCoord > maxBCoord)) {
// XXX When bug 765861 gets fixed, this warning should be upgraded.
NS_WARNING("bad block coord");
minBCoord = maxBCoord = 0;
}
LogicalSize size(rtcWM, mISize, maxBCoord - minBCoord);
nsSize containerSize = size.GetPhysicalSize(rtcWM);
for (nsIFrame* child : mFrames) {
// We reflowed the child with a dummy container size, as the true size
// was not yet known at that time.
LogicalPoint pos = child->GetLogicalPosition(rtcWM, dummyContainerSize);
// Adjust block position to account for minBCoord,
// then reposition child based on the true container width.
pos.B(rtcWM) -= minBCoord;
// Relative positioning hasn't happened yet.
// So MovePositionBy should not be used here.
child->SetPosition(rtcWM, pos, containerSize);
nsContainerFrame::PlaceFrameView(child);
}
aDesiredSize.SetSize(rtcWM, size);
} else {
// If this ruby text container is empty, size it as if there were
// an empty inline child inside.
// Border and padding are suppressed on ruby text container, so we
// create a dummy zero-sized borderPadding for setting BSize.
aDesiredSize.ISize(rtcWM) = mISize;
LogicalMargin borderPadding(rtcWM);
nsLayoutUtils::SetBSizeFromFontMetrics(this, aDesiredSize, borderPadding,
rtcWM, rtcWM);
}
}