mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 779971 - Make nsSVGTextPathProperty::DoUpdate trigger nsSVGTextFrame::NotifyGlyphMetricsChange() off an asynchronous change hint (to avoid calling nsLayoutUtils::FrameNeedsReflow synchronously under nsISVGChildFrame::ReflowSVG or during frame teardown, and avoid infinite loops caused by using an event queue event). r=jwatt.
--HG-- extra : rebase_source : 4dc4e59cf423f6ffb02826fb2f357edda85c048c
This commit is contained in:
parent
85ff52ec76
commit
9dc31645d1
@ -116,6 +116,7 @@
|
||||
#include "nsIDOMSVGFilters.h"
|
||||
#include "DOMSVGTests.h"
|
||||
#include "nsSVGEffects.h"
|
||||
#include "nsSVGTextPathFrame.h"
|
||||
#include "nsSVGUtils.h"
|
||||
|
||||
#include "nsRefreshDriver.h"
|
||||
@ -7797,6 +7798,12 @@ DoApplyRenderingChangeToTree(nsIFrame* aFrame,
|
||||
aFrame->InvalidateFrameSubtree();
|
||||
}
|
||||
}
|
||||
if (aChange & nsChangeHint_UpdateTextPath) {
|
||||
NS_ABORT_IF_FALSE(aFrame->GetType() == nsGkAtoms::svgTextPathFrame,
|
||||
"textPath frame expected");
|
||||
// Invalidate and reflow the entire nsSVGTextFrame:
|
||||
static_cast<nsSVGTextPathFrame*>(aFrame)->NotifyGlyphMetricsChange();
|
||||
}
|
||||
if (aChange & nsChangeHint_UpdateOpacityLayer) {
|
||||
// FIXME/bug 796697: we can get away with empty transactions for
|
||||
// opacity updates in many cases.
|
||||
|
@ -110,7 +110,13 @@ enum nsChangeHint {
|
||||
* changes, and it's inherited by a child, that might require a reflow
|
||||
* due to the border-width change on the child.
|
||||
*/
|
||||
nsChangeHint_BorderStyleNoneChange = 0x8000
|
||||
nsChangeHint_BorderStyleNoneChange = 0x8000,
|
||||
|
||||
/**
|
||||
* SVG textPath needs to be recomputed because the path has changed.
|
||||
* This means that the glyph positions of the text need to be recomputed.
|
||||
*/
|
||||
nsChangeHint_UpdateTextPath = 0x10000
|
||||
|
||||
// IMPORTANT NOTE: When adding new hints, consider whether you need to
|
||||
// add them to NS_HintsNotHandledForDescendantsIn() below.
|
||||
|
14
layout/svg/crashtests/779971-1.svg
Normal file
14
layout/svg/crashtests/779971-1.svg
Normal file
@ -0,0 +1,14 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="r" class="reftest-wait">
|
||||
<text id="t"><textPath xlink:href="#r">x</textPath>1</text>
|
||||
<script>
|
||||
|
||||
window.addEventListener("load", function() {
|
||||
setTimeout(function() {
|
||||
document.getElementById("t").lastChild.data = "2";
|
||||
|
||||
document.documentElement.removeAttribute("class");
|
||||
}, 200);
|
||||
}, false);
|
||||
|
||||
</script>
|
||||
</svg>
|
After Width: | Height: | Size: 416 B |
@ -136,6 +136,7 @@ load 767056-1.svg
|
||||
load 768351.svg
|
||||
load 780963-1.html
|
||||
load 757751-1.svg
|
||||
load 779971-1.svg
|
||||
load 782141-1.svg
|
||||
load 784061-1.svg
|
||||
load 790072.svg
|
||||
|
@ -286,32 +286,6 @@ nsSVGMarkerProperty::DoUpdate()
|
||||
mFrame->GetContent()->AsElement(), nsRestyleHint(0), changeHint);
|
||||
}
|
||||
|
||||
class nsAsyncNotifyGlyphMetricsChange MOZ_FINAL : public nsIReflowCallback
|
||||
{
|
||||
public:
|
||||
nsAsyncNotifyGlyphMetricsChange(nsIFrame* aFrame) : mWeakFrame(aFrame)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool ReflowFinished()
|
||||
{
|
||||
nsSVGTextPathFrame* frame =
|
||||
static_cast<nsSVGTextPathFrame*>(mWeakFrame.GetFrame());
|
||||
if (frame) {
|
||||
frame->NotifyGlyphMetricsChange();
|
||||
}
|
||||
delete this;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void ReflowCallbackCanceled()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
nsWeakFrame mWeakFrame;
|
||||
};
|
||||
|
||||
void
|
||||
nsSVGTextPathProperty::DoUpdate()
|
||||
{
|
||||
@ -322,13 +296,11 @@ nsSVGTextPathProperty::DoUpdate()
|
||||
NS_ASSERTION(mFrame->IsFrameOfType(nsIFrame::eSVG), "SVG frame expected");
|
||||
|
||||
if (mFrame->GetType() == nsGkAtoms::svgTextPathFrame) {
|
||||
if (mFrame->PresContext()->PresShell()->IsReflowLocked()) {
|
||||
nsIReflowCallback* cb = new nsAsyncNotifyGlyphMetricsChange(mFrame);
|
||||
mFrame->PresContext()->PresShell()->PostReflowCallback(cb);
|
||||
} else {
|
||||
nsSVGTextPathFrame* textPathFrame = static_cast<nsSVGTextPathFrame*>(mFrame);
|
||||
textPathFrame->NotifyGlyphMetricsChange();
|
||||
}
|
||||
// Repaint asynchronously in case the path frame is being torn down
|
||||
nsChangeHint changeHint =
|
||||
nsChangeHint(nsChangeHint_RepaintFrame | nsChangeHint_UpdateTextPath);
|
||||
mFramePresShell->FrameConstructor()->PostRestyleEvent(
|
||||
mFrame->GetContent()->AsElement(), nsRestyleHint(0), changeHint);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user