Bug 1844992 - refactor GetSubStringLength r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D184410
This commit is contained in:
Robert Longson 2023-07-27 10:15:23 +00:00
Родитель 4d9f9499f8
Коммит ad9a2a895e
3 изменённых файлов: 58 добавлений и 45 удалений

Просмотреть файл

@ -132,7 +132,20 @@ float SVGTextContentElement::GetSubStringLength(uint32_t charnum,
SVGTextFrame* textFrame = GetSVGTextFrameForNonLayoutDependentQuery();
if (!textFrame) return 0.0f;
return textFrame->GetSubStringLength(this, charnum, nchars, rv);
if (!textFrame->RequiresSlowFallbackForSubStringLength()) {
return textFrame->GetSubStringLengthFastPath(this, charnum, nchars, rv);
}
// We need to make sure that we've been reflowed before using the slow
// fallback path as it may affect glyph positioning. GetSVGTextFrame will do
// that for us.
// XXX perf: It may be possible to limit reflow to just calling ReflowSVG,
// but we would still need to resort to full reflow for percentage
// positioning attributes. For now we just do a full reflow regardless
// since the cases that would cause us to be called are relatively uncommon.
textFrame = GetSVGTextFrame();
if (!textFrame) return 0.0f;
return textFrame->GetSubStringLengthSlowFallback(this, charnum, nchars, rv);
}
already_AddRefed<DOMSVGPoint> SVGTextContentElement::GetStartPositionOfChar(

Просмотреть файл

@ -3509,34 +3509,43 @@ void SVGTextFrame::SelectSubString(nsIContent* aContent, uint32_t charnum,
}
/**
* Implements the SVG DOM GetSubStringLength method for the specified
* text content element.
* For some content we cannot (or currently cannot) compute the length
* without reflowing. In those cases we need to fall back to using
* GetSubStringLengthSlowFallback.
*
* We fall back for textPath since we need glyph positioning in order to
* tell if any characters should be ignored due to having fallen off the
* end of the textPath.
*
* We fall back for bidi because GetTrimmedOffsets does not produce the
* correct results for bidi continuations when passed aPostReflow = false.
* XXX It may be possible to determine which continuations to trim from (and
* which sides), but currently we don't do that. It would require us to
* identify the visual (rather than logical) start and end of the line, to
* avoid trimming at line-internal frame boundaries. Maybe nsBidiPresUtils
* methods like GetFrameToRightOf and GetFrameToLeftOf would help?
*
*/
float SVGTextFrame::GetSubStringLength(nsIContent* aContent, uint32_t charnum,
uint32_t nchars, ErrorResult& aRv) {
// For some content we cannot (or currently cannot) compute the length
// without reflowing. In those cases we need to fall back to using
// GetSubStringLengthSlowFallback.
//
// We fall back for textPath since we need glyph positioning in order to
// tell if any characters should be ignored due to having fallen off the
// end of the textPath.
//
// We fall back for bidi because GetTrimmedOffsets does not produce the
// correct results for bidi continuations when passed aPostReflow = false.
// XXX It may be possible to determine which continuations to trim from (and
// which sides), but currently we don't do that. It would require us to
// identify the visual (rather than logical) start and end of the line, to
// avoid trimming at line-internal frame boundaries. Maybe nsBidiPresUtils
// methods like GetFrameToRightOf and GetFrameToLeftOf would help?
//
bool SVGTextFrame::RequiresSlowFallbackForSubStringLength() {
TextFrameIterator frameIter(this);
for (nsTextFrame* frame = frameIter.Current(); frame;
frame = frameIter.Next()) {
if (frameIter.TextPathFrame() || frame->GetNextContinuation()) {
return GetSubStringLengthSlowFallback(aContent, charnum, nchars, aRv);
return true;
}
}
return false;
}
/**
* Implements the SVG DOM GetSubStringLength method for the specified
* text content element.
*/
float SVGTextFrame::GetSubStringLengthFastPath(nsIContent* aContent,
uint32_t charnum,
uint32_t nchars,
ErrorResult& aRv) {
MOZ_ASSERT(!RequiresSlowFallbackForSubStringLength());
// We only need our text correspondence to be up to date (no need to call
// UpdateGlyphPositioning).
@ -3630,15 +3639,6 @@ float SVGTextFrame::GetSubStringLengthSlowFallback(nsIContent* aContent,
uint32_t charnum,
uint32_t nchars,
ErrorResult& aRv) {
// We need to make sure that we've been reflowed before updating the glyph
// positioning.
// XXX perf: It may be possible to limit reflow to just calling ReflowSVG,
// but we would still need to resort to full reflow for percentage
// positioning attributes. For now we just do a full reflow regardless since
// the cases that would cause us to be called are relatively uncommon.
RefPtr<mozilla::PresShell> presShell = PresShell();
presShell->FlushPendingNotifications(FlushType::Layout);
UpdateGlyphPositioning();
// Convert charnum/nchars from addressable characters relative to

Просмотреть файл

@ -241,9 +241,20 @@ class SVGTextFrame final : public SVGDisplayContainerFrame {
uint32_t charnum,
uint32_t nchars,
ErrorResult& aRv);
MOZ_CAN_RUN_SCRIPT
float GetSubStringLength(nsIContent* aContent, uint32_t charnum,
uint32_t nchars, ErrorResult& aRv);
bool RequiresSlowFallbackForSubStringLength();
float GetSubStringLengthFastPath(nsIContent* aContent, uint32_t charnum,
uint32_t nchars, ErrorResult& aRv);
/**
* This fallback version of GetSubStringLength takes
* into account glyph positioning and requires us to have flushed layout
* before calling it. As per the SVG 2 spec, typically glyph
* positioning does not affect the results of getSubStringLength, but one
* exception is text in a textPath where we need to ignore characters that
* fall off the end of the textPath path.
*/
float GetSubStringLengthSlowFallback(nsIContent* aContent, uint32_t charnum,
uint32_t nchars, ErrorResult& aRv);
int32_t GetCharNumAtPosition(nsIContent* aContent,
const dom::DOMPointInit& aPoint);
@ -405,17 +416,6 @@ class SVGTextFrame final : public SVGDisplayContainerFrame {
*/
void DoGlyphPositioning();
/**
* This fallback version of GetSubStringLength that flushes layout and takes
* into account glyph positioning. As per the SVG 2 spec, typically glyph
* positioning does not affect the results of getSubStringLength, but one
* exception is text in a textPath where we need to ignore characters that
* fall off the end of the textPath path.
*/
MOZ_CAN_RUN_SCRIPT
float GetSubStringLengthSlowFallback(nsIContent* aContent, uint32_t charnum,
uint32_t nchars, ErrorResult& aRv);
/**
* Converts the specified index into mPositions to an addressable
* character index (as can be used with the SVG DOM text methods)