Although I haven't been able to reproduce the reporter's OOM crash here, I hope this will avoid
the issue; it certainly improves performance characteristics in my local build.
On the example here, my laptop happily scrolls the text field at 60fps when nothing is selected;
but if the text is selected it can only manage around 40fps, because we lose the clipping
optimization here.
With this change, it maintains 60fps regardless of whether the text is selected (or text-shadow
is present), and memory footprint is substantially reduced.
Differential Revision: https://phabricator.services.mozilla.com/D171318
Before, there existed 3 virtual functions that calculated baselines:
- `GetLogicalBaseline`
- `GetVerticalAlignBaseline`
- `GetNaturalBaselineBOffset`
Each of them had slightly different behaviours:
- `GetLogicalBaseline` would synthesize a baseline if there is no baseline.
Others would simply return `false`.
- `GetNaturalBaselineBOffset` requires the caller to pick which of first/last
baseline to calculate. Others pick on on their own.
- `GetNaturalBaselineBOffset`'s result can be either offset from border box
start/end edge, depending on the caller-supplied baseline. Others always
return offset from border box start edge.
Now:
- `GetNaturalBaselineBOffset` is the sole virtual function.
- `GetLogicalBaseline` exists to support its use, with 2 virtual helper functions:
- `SynthesizeFallbackBaseline` to generate a baseline for elements that
doesn't have one.
- `GetBaselineSharingGroup` to preserve the default baseline picking behaviour.
Differential Revision: https://phabricator.services.mozilla.com/D167990
With this, the old SelectionIterator that expects a per-character array of
SelectionDetails pointers is no longer used anywhere.
Differential Revision: https://phabricator.services.mozilla.com/D170588
This significantly improves performance and reduces memory usage when painting a very long textframe
with some or all of the text selected.
Differential Revision: https://phabricator.services.mozilla.com/D170530
Added WebIDL interfaces as per spec, added some necessary changes to support maplike and setlike structures to be accessed from C++.
Added `::highlight(foo)` pseudo element to CSS engine.
Implemented Highlight as new kind of `Selection` using `HighlightType::eHighlight`. This implies Selections being added/removed during runtime (one `Selection` object per highlight identifier), therefore a dynamic container for highlight `Selection` objects was added to `nsFrameSelection`. Also, the painting code queries the highlight style for highlight Selections.
Implementation is currently hidden behind a pref `dom.customHighlightAPI.enabled`.
Differential Revision: https://phabricator.services.mozilla.com/D164203
Added WebIDL interfaces as per spec, added some necessary changes to support maplike and setlike structures to be accessed from C++.
Added `::highlight(foo)` pseudo element to CSS engine.
Implemented Highlight as new kind of `Selection` using `HighlightType::eHighlight`. This implies Selections being added/removed during runtime (one `Selection` object per highlight identifier), therefore a dynamic container for highlight `Selection` objects was added to `nsFrameSelection`. Also, the painting code queries the highlight style for highlight Selections.
Implementation is currently hidden behind a pref `dom.customHighlightAPI.enabled`.
Differential Revision: https://phabricator.services.mozilla.com/D164203
Added WebIDL interfaces as per spec, added some necessary changes to support maplike and setlike structures to be accessed from C++.
Added `::highlight(foo)` pseudo element to CSS engine.
Implemented Highlight as new kind of `Selection` using `HighlightType::eHighlight`. This implies Selections being added/removed during runtime (one `Selection` object per highlight identifier), therefore a dynamic container for highlight `Selection` objects was added to `nsFrameSelection`. Also, the painting code queries the highlight style for highlight Selections.
Implementation is currently hidden behind a pref `dom.customHighlightAPI.enabled`.
Differential Revision: https://phabricator.services.mozilla.com/D164203
Added WebIDL interfaces as per spec, added some necessary changes to support maplike and setlike structures to be accessed from C++.
Added `::highlight(foo)` pseudo element to CSS engine.
Implemented Highlight as new kind of `Selection` using `HighlightType::eHighlight`. This implies Selections being added/removed during runtime (one `Selection` object per highlight identifier), therefore a dynamic container for highlight `Selection` objects was added to `nsFrameSelection`. Also, the painting code queries the highlight style for highlight Selections.
Implementation is currently hidden behind a pref `dom.customHighlightAPI.enabled`.
Differential Revision: https://phabricator.services.mozilla.com/D164203
Historically, Gecko implemented the behavior allowed by CSS2 whereby a floated ::first-letter is "boxed"
tightly around the glyph shape, rather than using constant font-ascent and -descent metrics which may
leave a lot of blank space depending whether the character has any ascender/descender or not.
However, neither webkit nor blink do this, which leads to webcompat pain when sites are constructed
assuming their behavior.
Eventually, I think we should ideally reimplement ::first-letter entirely at frame-construction time,
rather than during reflow. But in the interest of minimizing risk here, and making it easy to flip
between our existing "legacy" behavior and the new "compatible" behavior, this patch leaves the
overall implementation unchanged and just alters the metrics used for the resulting first-letter
frame.
This patch creates an integer pref layout.css.floating-first-letter.tight-glyph-bounds to allow us
to choose between three behaviors:
1: Use tight glyph bounds, and ignore line-height; the baseline of the floated letter automatically
adjusts to wrap text around the "ink box" of the glyph. This is the existing Gecko behavior.
0: Don't use tight glyph bounds, respect line-height: the floated letter acts like a normal <span>
with float positioning; baseline position and vertical size are based on font metrics but not
the specific shape of the individual glyph. This gives a similar result to webkit/blink.
-1: Automatically choose between (1) and (0) based on heuristics to try and detect whether the page
was written with the webkit/blink behavior (0) in mind; specifically, if there is a line-height
of less than 1em, or a negative block-start margin, we assume the author was trying to eliminate
excess blank space that behavior (0) tends to produce, and so we use that model.
Initially, this patch leaves the behavior unchanged for Beta/Release builds, but enables option -1 (use
heuristics to choose which layout model to apply) on Nightly so we can see how that works in practice.
Differential Revision: https://phabricator.services.mozilla.com/D165008
Historically, Gecko implemented the behavior allowed by CSS2 whereby a floated ::first-letter is "boxed"
tightly around the glyph shape, rather than using constant font-ascent and -descent metrics which may
leave a lot of blank space depending whether the character has any ascender/descender or not.
However, neither webkit nor blink do this, which leads to webcompat pain when sites are constructed
assuming their behavior.
Eventually, I think we should ideally reimplement ::first-letter entirely at frame-construction time,
rather than during reflow. But in the interest of minimizing risk here, and making it easy to flip
between our existing "legacy" behavior and the new "compatible" behavior, this patch leaves the
overall implementation unchanged and just alters the metrics used for the resulting first-letter
frame.
This patch creates an integer pref layout.css.floating-first-letter.tight-glyph-bounds to allow us
to choose between three behaviors:
1: Use tight glyph bounds, and ignore line-height; the baseline of the floated letter automatically
adjusts to wrap text around the "ink box" of the glyph. This is the existing Gecko behavior.
0: Don't use tight glyph bounds, respect line-height: the floated letter acts like a normal <span>
with float positioning; baseline position and vertical size are based on font metrics but not
the specific shape of the individual glyph. This gives a similar result to webkit/blink.
-1: Automatically choose between (1) and (0) based on heuristics to try and detect whether the page
was written with the webkit/blink behavior (0) in mind; specifically, if there is a line-height
of less than 1em, or a negative block-start margin, we assume the author was trying to eliminate
excess blank space that behavior (0) tends to produce, and so we use that model.
Initially, this patch leaves the behavior unchanged for Beta/Release builds, but enables option -1 (use
heuristics to choose which layout model to apply) on Nightly so we can see how that works in practice.
Differential Revision: https://phabricator.services.mozilla.com/D165008
This patch doesn't impact behavior; it's just adding an annotation to activate
a static analysis check for various classes.
The annotation gives us some confidence that these instances are tightly scoped
to a particular function-call. This helps reduce concerns about to-what-extent
the affected classes might need to worry about the lifetimes of the objects
pointed to by their member-vars.
The specific classes I'm annotating are:
- gfxTextRunDrawCallbacks and PaintTextParams, both of which have multiple
subclasses, all of which will automatically inherit this annotation and
benefit from it.
- TextFrameIterator and CharIterator, two local utility classes in
SVGTextFrame.cpp.
Differential Revision: https://phabricator.services.mozilla.com/D160694
Before this patch, we had two `checkVisibilty` methods on the
nsISelectionController interface, backed by several layers of implementation,
ultimately backed by a single function on nsTextFrame (which didn't actually
do anything meaningful with any of the parameters).
As it turns out, this API only had one caller, in HTMLEditUtils.cpp.
This patch converts that caller to directly query nsTextFrame (if the given
node's primary frame is indeed a nsTextFrame). The direct function-call is
renamed to HasVisibleText(), to be a bit clearer about it being text-specific
and also to avoid confusion with the (unrelated) recently-specified HTML
checkVisibility() API.
With these changes, we can remove the API from the nsISelectionController
interface and its implementations.
This patch also updates the HTMLEditUtils::IsInVisibleTextFrames documentation
(with s/all/any/) to reflect the reality of what the nsTextFrame impl actually
does.
Differential Revision: https://phabricator.services.mozilla.com/D160563
Some sites use text content that consists entirely of whitespace, which can
lead to unexpected rendering in High Contrast Mode - namely, backplating of
invisible characters. This commit adds logic that detects text nodes consisting
entirely of whitespace and reports their text area as 0. This commit also adds
a test for the behavior, and modifies an existing test to reflect the new
behavior.
Differential Revision: https://phabricator.services.mozilla.com/D155248
After CollectClientRectsAndText is eliminated from the profiles here, SelectionStateChanged
is the next obvious hotspot, and it can similarly be accelerated by binary-searching the continuations.
Depends on D122999
Differential Revision: https://phabricator.services.mozilla.com/D123000
This allows us to binary-search the continuations from nsRange::CollectClientRectsAndText,
instead of linear-searching the linked list for every range we need to look up.
Depends on D122998
Differential Revision: https://phabricator.services.mozilla.com/D122999
This is helpful when we have extremely long continuation chains, to avoid having to
follow all the back-pointers to find the primary frame. By itself it makes little
difference to the testcase here, but is a basis for the patch that follows.
Differential Revision: https://phabricator.services.mozilla.com/D122998
CLOSED TREE
Backed out changeset d0864a5c8e90 (bug 1725555)
Backed out changeset 22b941581212 (bug 1725555)
Backed out changeset f2357e055668 (bug 1725555)
After CollectClientRectsAndText is eliminated from the profiles here, SelectionStateChanged
is the next obvious hotspot, and it can similarly be accelerated by binary-searching the continuations.
Depends on D122999
Differential Revision: https://phabricator.services.mozilla.com/D123000
This allows us to binary-search the continuations from nsRange::CollectClientRectsAndText,
instead of linear-searching the linked list for every range we need to look up.
Depends on D122998
Differential Revision: https://phabricator.services.mozilla.com/D122999
This is helpful when we have extremely long continuation chains, to avoid having to
follow all the back-pointers to find the primary frame. By itself it makes little
difference to the testcase here, but is a basis for the patch that follows.
Differential Revision: https://phabricator.services.mozilla.com/D122998
After CollectClientRectsAndText is eliminated from the profiles here, SelectionStateChanged
is the next obvious hotspot, and it can similarly be accelerated by binary-searching the continuations.
Depends on D122999
Differential Revision: https://phabricator.services.mozilla.com/D123000
This allows us to binary-search the continuations from nsRange::CollectClientRectsAndText,
instead of linear-searching the linked list for every range we need to look up.
Depends on D122998
Differential Revision: https://phabricator.services.mozilla.com/D122999
This is helpful when we have extremely long continuation chains, to avoid having to
follow all the back-pointers to find the primary frame. By itself it makes little
difference to the testcase here, but is a basis for the patch that follows.
Differential Revision: https://phabricator.services.mozilla.com/D122998
After CollectClientRectsAndText is eliminated from the profiles here, SelectionStateChanged
is the next obvious hotspot, and it can similarly be accelerated by binary-searching the continuations.
Depends on D122999
Differential Revision: https://phabricator.services.mozilla.com/D123000
This allows us to binary-search the continuations from nsRange::CollectClientRectsAndText,
instead of linear-searching the linked list for every range we need to look up.
Depends on D122998
Differential Revision: https://phabricator.services.mozilla.com/D122999
This is helpful when we have extremely long continuation chains, to avoid having to
follow all the back-pointers to find the primary frame. By itself it makes little
difference to the testcase here, but is a basis for the patch that follows.
Differential Revision: https://phabricator.services.mozilla.com/D122998