Skip to content

Commit

Permalink
Bug 1524328 - Don't resolve counter styles in the style system. r=xidorn
Browse files Browse the repository at this point in the history
Doing it during layout instead. This also has the nice side-effect of
no longer needing to do a full restyle when counter-style rules are inserted.

Differential Revision: https://phabricator.services.mozilla.com/D18343
  • Loading branch information
emilio committed Feb 3, 2019
1 parent 8e5ab99 commit 30de825
Show file tree
Hide file tree
Showing 11 changed files with 180 additions and 229 deletions.
8 changes: 5 additions & 3 deletions layout/base/nsCounterManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,15 @@ void nsCounterUseNode::GetText(nsString& aResult) {
}
}

WritingMode wm =
mPseudoFrame ? mPseudoFrame->GetWritingMode() : WritingMode();
WritingMode wm = mPseudoFrame->GetWritingMode();
CounterStyle* style =
mPseudoFrame->PresContext()->CounterStyleManager()->ResolveCounterStyle(
mCounterStyle);
for (uint32_t i = stack.Length() - 1;; --i) {
nsCounterNode* n = stack[i];
nsAutoString text;
bool isTextRTL;
mCounterStyle->GetCounterText(n->mValueAfter, wm, text, isTextRTL);
style->GetCounterText(n->mValueAfter, wm, text, isTextRTL);
aResult.Append(text);
if (i == 0) {
break;
Expand Down
3 changes: 1 addition & 2 deletions layout/base/nsPresContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1931,8 +1931,7 @@ void nsPresContext::FlushCounterStyles() {
bool changed = mCounterStyleManager->NotifyRuleChanged();
if (changed) {
PresShell()->NotifyCounterStylesAreDirty();
PostRebuildAllStyleDataEvent(NS_STYLE_HINT_REFLOW,
eRestyle_ForceDescendants);
PostRebuildAllStyleDataEvent(NS_STYLE_HINT_REFLOW, nsRestyleHint(0));
RefreshDriver()->AddPostRefreshObserver(
new CounterStyleCleaner(RefreshDriver(), mCounterStyleManager));
}
Expand Down
41 changes: 26 additions & 15 deletions layout/generic/ReflowInput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,21 +136,32 @@ static nscoord FontSizeInflationListMarginAdjustment(const nsIFrame* aFrame) {
}

float inflation = nsLayoutUtils::FontSizeInflationFor(aFrame);
if (inflation > 1.0f) {
auto listStyleType = aFrame->StyleList()->mCounterStyle->GetStyle();
if (listStyleType != NS_STYLE_LIST_STYLE_NONE &&
listStyleType != NS_STYLE_LIST_STYLE_DISC &&
listStyleType != NS_STYLE_LIST_STYLE_CIRCLE &&
listStyleType != NS_STYLE_LIST_STYLE_SQUARE &&
listStyleType != NS_STYLE_LIST_STYLE_DISCLOSURE_CLOSED &&
listStyleType != NS_STYLE_LIST_STYLE_DISCLOSURE_OPEN) {
// The HTML spec states that the default padding for ordered lists
// begins at 40px, indicating that we have 40px of space to place a
// bullet. When performing font inflation calculations, we add space
// equivalent to this, but simply inflated at the same amount as the
// text, in app units.
return nsPresContext::CSSPixelsToAppUnits(40) * (inflation - 1);
}
if (inflation <= 1.0f) {
return 0;
}

// The HTML spec states that the default padding for ordered lists
// begins at 40px, indicating that we have 40px of space to place a
// bullet. When performing font inflation calculations, we add space
// equivalent to this, but simply inflated at the same amount as the
// text, in app units.
auto margin = nsPresContext::CSSPixelsToAppUnits(40) * (inflation - 1);

auto* list = aFrame->StyleList();
if (!list->mCounterStyle.IsAtom()) {
return margin;
}

// NOTE(emilio): @counter-style can override some of the styles from this
// list, and we won't add margin to the counter.
//
// See https://github.com/w3c/csswg-drafts/issues/3584
nsAtom* type = list->mCounterStyle.AsAtom();
if (type != nsGkAtoms::none && type != nsGkAtoms::disc &&
type != nsGkAtoms::circle && type != nsGkAtoms::square &&
type != nsGkAtoms::disclosure_closed &&
type != nsGkAtoms::disclosure_open) {
return margin;
}

return 0;
Expand Down
9 changes: 6 additions & 3 deletions layout/generic/nsBlockFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6783,10 +6783,13 @@ void nsBlockFrame::CreateBulletFrameForListItem() {
NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET)) == 0,
"How can we have a bullet already?");

nsIPresShell* shell = PresShell();
nsPresContext* pc = PresContext();
nsIPresShell* shell = pc->PresShell();
const nsStyleList* styleList = StyleList();
CounterStyle* style =
pc->CounterStyleManager()->ResolveCounterStyle(styleList->mCounterStyle);

CSSPseudoElementType pseudoType = styleList->mCounterStyle->IsBullet()
CSSPseudoElementType pseudoType = style->IsBullet()
? CSSPseudoElementType::mozListBullet
: CSSPseudoElementType::mozListNumber;

Expand Down Expand Up @@ -6817,7 +6820,7 @@ bool nsBlockFrame::BulletIsEmpty() const {
HasOutsideBullet(),
"should only care when we have an outside bullet");
const nsStyleList* list = StyleList();
return list->mCounterStyle->IsNone() && !list->GetListStyleImage();
return list->mCounterStyle.IsNone() && !list->GetListStyleImage();
}

void nsBlockFrame::GetSpokenBulletText(nsAString& aText) const {
Expand Down
122 changes: 69 additions & 53 deletions layout/generic/nsBulletFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ using namespace mozilla;
using namespace mozilla::gfx;
using namespace mozilla::image;
using namespace mozilla::layout;
using mozilla::dom::Document;

NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(FontSizeInflationProperty, float)

Expand All @@ -65,6 +66,11 @@ NS_QUERYFRAME_TAIL_INHERITING(nsFrame)

nsBulletFrame::~nsBulletFrame() {}

CounterStyle* nsBulletFrame::ResolveCounterStyle() {
return PresContext()->CounterStyleManager()->ResolveCounterStyle(
StyleList()->mCounterStyle);
}

void nsBulletFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
// Stop image loading first.
Expand All @@ -87,7 +93,7 @@ nsresult nsBulletFrame::GetFrameName(nsAString& aResult) const {
bool nsBulletFrame::IsEmpty() { return IsSelfEmpty(); }

bool nsBulletFrame::IsSelfEmpty() {
return StyleList()->mCounterStyle->IsNone();
return StyleList()->mCounterStyle.IsNone();
}

/* virtual */ void nsBulletFrame::DidSetComputedStyle(
Expand Down Expand Up @@ -147,11 +153,11 @@ bool nsBulletFrame::IsSelfEmpty() {
const nsStyleList* oldStyleList = aOldComputedStyle->PeekStyleList();
if (oldStyleList) {
bool hadBullet = oldStyleList->GetListStyleImage() ||
!oldStyleList->mCounterStyle->IsNone();
!oldStyleList->mCounterStyle.IsNone();

const nsStyleList* newStyleList = StyleList();
bool hasBullet = newStyleList->GetListStyleImage() ||
!newStyleList->mCounterStyle->IsNone();
!newStyleList->mCounterStyle.IsNone();

if (hadBullet != hasBullet) {
accService->UpdateListBullet(PresContext()->GetPresShell(), mContent,
Expand Down Expand Up @@ -650,7 +656,7 @@ void nsBulletFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
Maybe<BulletRenderer> nsBulletFrame::CreateBulletRenderer(
gfxContext& aRenderingContext, nsPoint aPt) {
const nsStyleList* myList = StyleList();
CounterStyle* listStyleType = myList->mCounterStyle;
CounterStyle* listStyleType = ResolveCounterStyle();
nsMargin padding = mPadding.GetPhysicalMargin(GetWritingMode());

if (myList->GetListStyleImage() && mImageRequest) {
Expand Down Expand Up @@ -766,7 +772,7 @@ Maybe<BulletRenderer> nsBulletFrame::CreateBulletRenderer(
RefPtr<nsFontMetrics> fm =
nsLayoutUtils::GetFontMetricsForFrame(this, GetFontSizeInflation());
nsAutoString text;
GetListItemText(text);
GetListItemText(listStyleType, GetWritingMode(), GetOrdinal(), text);
WritingMode wm = GetWritingMode();
nscoord ascent = wm.IsLineInverted() ? fm->MaxDescent() : fm->MaxAscent();
aPt.MoveBy(padding.left, padding.top);
Expand Down Expand Up @@ -835,25 +841,27 @@ int32_t nsBulletFrame::SetListItemOrdinal(int32_t aNextOrdinal, bool* aChanged,
return nsCounterManager::IncrementCounter(mOrdinal, aIncrement);
}

void nsBulletFrame::GetListItemText(nsAString& aResult) {
CounterStyle* style = StyleList()->mCounterStyle;
NS_ASSERTION(style->GetStyle() != NS_STYLE_LIST_STYLE_NONE &&
style->GetStyle() != NS_STYLE_LIST_STYLE_DISC &&
style->GetStyle() != NS_STYLE_LIST_STYLE_CIRCLE &&
style->GetStyle() != NS_STYLE_LIST_STYLE_SQUARE &&
style->GetStyle() != NS_STYLE_LIST_STYLE_DISCLOSURE_CLOSED &&
style->GetStyle() != NS_STYLE_LIST_STYLE_DISCLOSURE_OPEN,
"we should be using specialized code for these types");
void nsBulletFrame::GetListItemText(CounterStyle* aStyle,
mozilla::WritingMode aWritingMode,
int32_t aOrdinal, nsAString& aResult) {
NS_ASSERTION(
aStyle->GetStyle() != NS_STYLE_LIST_STYLE_NONE &&
aStyle->GetStyle() != NS_STYLE_LIST_STYLE_DISC &&
aStyle->GetStyle() != NS_STYLE_LIST_STYLE_CIRCLE &&
aStyle->GetStyle() != NS_STYLE_LIST_STYLE_SQUARE &&
aStyle->GetStyle() != NS_STYLE_LIST_STYLE_DISCLOSURE_CLOSED &&
aStyle->GetStyle() != NS_STYLE_LIST_STYLE_DISCLOSURE_OPEN,
"we should be using specialized code for these types");

bool isRTL;
nsAutoString counter, prefix, suffix;
style->GetPrefix(prefix);
style->GetSuffix(suffix);
style->GetCounterText(mOrdinal, GetWritingMode(), counter, isRTL);
aStyle->GetPrefix(prefix);
aStyle->GetSuffix(suffix);
aStyle->GetCounterText(aOrdinal, aWritingMode, counter, isRTL);

aResult.Truncate();
aResult.Append(prefix);
if (GetWritingMode().IsBidiLTR() != isRTL) {
if (aWritingMode.IsBidiLTR() != isRTL) {
aResult.Append(counter);
} else {
// RLM = 0x200f, LRM = 0x200e
Expand Down Expand Up @@ -919,7 +927,8 @@ void nsBulletFrame::GetDesiredSize(nsPresContext* aCX,
nscoord bulletSize;

nsAutoString text;
switch (myList->mCounterStyle->GetStyle()) {
CounterStyle* style = ResolveCounterStyle();
switch (style->GetStyle()) {
case NS_STYLE_LIST_STYLE_NONE:
finalSize.ISize(wm) = finalSize.BSize(wm) = 0;
aMetrics.SetBlockStartAscent(0);
Expand Down Expand Up @@ -952,7 +961,7 @@ void nsBulletFrame::GetDesiredSize(nsPresContext* aCX,
break;

default:
GetListItemText(text);
GetListItemText(style, GetWritingMode(), GetOrdinal(), text);
finalSize.BSize(wm) = fm->MaxHeight();
finalSize.ISize(wm) = nsLayoutUtils::AppUnitWidthOfStringBidi(
text, this, *fm, *aRenderingContext);
Expand Down Expand Up @@ -1034,7 +1043,7 @@ static inline bool IsIgnoreable(const nsIFrame* aFrame, nscoord aISize) {
return false;
}
auto listStyle = aFrame->StyleList();
return listStyle->mCounterStyle->IsNone() && !listStyle->GetListStyleImage();
return listStyle->mCounterStyle.IsNone() && !listStyle->GetListStyleImage();
}

/* virtual */ void nsBulletFrame::AddInlineMinISize(
Expand Down Expand Up @@ -1209,47 +1218,54 @@ already_AddRefed<imgIContainer> nsBulletFrame::GetImage() const {
return nullptr;
}

nscoord nsBulletFrame::GetListStyleAscent() const {
RefPtr<nsFontMetrics> fm =
nsLayoutUtils::GetFontMetricsForFrame(this, GetFontSizeInflation());
auto* list = StyleList();
if (list->mCounterStyle.IsNone()) {
return 0;
}
if (list->mCounterStyle.IsAnonymous()) {
return fm->MaxAscent();
}
// NOTE(emilio): @counter-style can override most of the styles from this
// list, and we still return the changed ascent. Do we care about that?
//
// https://github.com/w3c/csswg-drafts/issues/3584
nsAtom* style = list->mCounterStyle.AsAtom();
if (style == nsGkAtoms::disc || style == nsGkAtoms::circle ||
style == nsGkAtoms::square) {
nscoord ascent = fm->MaxAscent();
nscoord baselinePadding = NSToCoordRound(float(ascent) / 8.0f);
ascent = std::max(nsPresContext::CSSPixelsToAppUnits(MIN_BULLET_SIZE),
NSToCoordRound(0.8f * (float(ascent) / 2.0f)));
return ascent + baselinePadding;
}
if (style == nsGkAtoms::disclosure_open ||
style == nsGkAtoms::disclosure_closed) {
nscoord ascent = fm->EmAscent();
nscoord baselinePadding = NSToCoordRound(0.125f * ascent);
ascent = std::max(nsPresContext::CSSPixelsToAppUnits(MIN_BULLET_SIZE),
NSToCoordRound(0.75f * ascent));
return ascent + baselinePadding;
}
return fm->MaxAscent();
}

nscoord nsBulletFrame::GetLogicalBaseline(WritingMode aWritingMode) const {
nscoord ascent = 0, baselinePadding;
nscoord ascent = 0;
if (GetStateBits() & BULLET_FRAME_IMAGE_LOADING) {
ascent = BSize(aWritingMode);
} else {
RefPtr<nsFontMetrics> fm =
nsLayoutUtils::GetFontMetricsForFrame(this, GetFontSizeInflation());
CounterStyle* listStyleType = StyleList()->mCounterStyle;
switch (listStyleType->GetStyle()) {
case NS_STYLE_LIST_STYLE_NONE:
break;

case NS_STYLE_LIST_STYLE_DISC:
case NS_STYLE_LIST_STYLE_CIRCLE:
case NS_STYLE_LIST_STYLE_SQUARE:
ascent = fm->MaxAscent();
baselinePadding = NSToCoordRound(float(ascent) / 8.0f);
ascent = std::max(nsPresContext::CSSPixelsToAppUnits(MIN_BULLET_SIZE),
NSToCoordRound(0.8f * (float(ascent) / 2.0f)));
ascent += baselinePadding;
break;

case NS_STYLE_LIST_STYLE_DISCLOSURE_CLOSED:
case NS_STYLE_LIST_STYLE_DISCLOSURE_OPEN:
ascent = fm->EmAscent();
baselinePadding = NSToCoordRound(0.125f * ascent);
ascent = std::max(nsPresContext::CSSPixelsToAppUnits(MIN_BULLET_SIZE),
NSToCoordRound(0.75f * ascent));
ascent += baselinePadding;
break;

default:
ascent = fm->MaxAscent();
break;
}
ascent = GetListStyleAscent();
}
return ascent + GetLogicalUsedMargin(aWritingMode).BStart(aWritingMode);
}

void nsBulletFrame::GetSpokenText(nsAString& aText) {
CounterStyle* style = StyleList()->mCounterStyle;
CounterStyle* style =
PresContext()->CounterStyleManager()->ResolveCounterStyle(
StyleList()->mCounterStyle);
bool isBullet;
style->GetSpokenCounterText(mOrdinal, GetWritingMode(), aText, isBullet);
if (isBullet) {
Expand Down
5 changes: 4 additions & 1 deletion layout/generic/nsBulletFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ class nsBulletFrame final : public nsFrame {
int32_t aIncrement);

/* get list item text, with prefix & suffix */
void GetListItemText(nsAString& aResult);
static void GetListItemText(mozilla::CounterStyle*, mozilla::WritingMode,
int32_t aOrdinal, nsAString& aResult);

void GetSpokenText(nsAString& aText);

Expand Down Expand Up @@ -139,6 +140,8 @@ class nsBulletFrame final : public nsFrame {
int32_t mOrdinal;

private:
mozilla::CounterStyle* ResolveCounterStyle();
nscoord GetListStyleAscent() const;
void RegisterImageRequest(bool aKnownToBeAnimated);
void DeregisterAndCancelImageRequest();

Expand Down
Loading

0 comments on commit 30de825

Please sign in to comment.