diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index ea952f125716..0dab1645cff6 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -1014,7 +1014,7 @@ CanvasRenderingContext2D::ParseColor(const nsAString& aString, *aColor = value.GetColorValue(); } else { // otherwise resolve it - nsIPresShell* presShell = GetPresShell(); + nsCOMPtr presShell = GetPresShell(); nsRefPtr parentContext; if (mCanvasElement && mCanvasElement->IsInDoc()) { // Inherit from the canvas element. @@ -2151,9 +2151,15 @@ GetFontParentStyleContext(Element* aElement, nsIPresShell* presShell, ErrorResult& error) { if (aElement && aElement->IsInDoc()) { - // inherit from the canvas element - return nsComputedDOMStyle::GetStyleContextForElement(aElement, nullptr, - presShell); + // Inherit from the canvas element. + nsRefPtr result = + nsComputedDOMStyle::GetStyleContextForElement(aElement, nullptr, + presShell); + if (!result) { + error.Throw(NS_ERROR_FAILURE); + return nullptr; + } + return result.forget(); } // otherwise inherit from default (10px sans-serif) @@ -2168,7 +2174,14 @@ GetFontParentStyleContext(Element* aElement, nsIPresShell* presShell, nsTArray> parentRules; parentRules.AppendElement(parentRule); - return presShell->StyleSet()->ResolveStyleForRules(nullptr, parentRules); + nsRefPtr result = + presShell->StyleSet()->ResolveStyleForRules(nullptr, parentRules); + + if (!result) { + error.Throw(NS_ERROR_FAILURE); + return nullptr; + } + return result.forget(); } static bool @@ -2222,6 +2235,12 @@ GetFontStyleContext(Element* aElement, const nsAString& aFont, return nullptr; } + MOZ_RELEASE_ASSERT(parentContext, + "GetFontParentStyleContext should have returned an error if it couldn't get a parent context."); + + MOZ_ASSERT(!presShell->IsDestroying(), + "GetFontParentStyleContext should have returned an error if the presshell is being destroyed."); + nsTArray> rules; rules.AppendElement(rule); // add a rule to prevent text zoom from affecting the style @@ -2299,7 +2318,7 @@ CanvasRenderingContext2D::ParseFilter(const nsAString& aString, return false; } - nsIPresShell* presShell = GetPresShell(); + nsCOMPtr presShell = GetPresShell(); if (!presShell) { error.Throw(NS_ERROR_FAILURE); return false; @@ -3034,6 +3053,13 @@ CanvasRenderingContext2D::TransformWillUpdate() void CanvasRenderingContext2D::SetFont(const nsAString& font, ErrorResult& error) +{ + SetFontInternal(font, error); +} + +bool +CanvasRenderingContext2D::SetFontInternal(const nsAString& font, + ErrorResult& error) { /* * If font is defined with relative units (e.g. ems) and the parent @@ -3046,20 +3072,20 @@ CanvasRenderingContext2D::SetFont(const nsAString& font, if (!mCanvasElement && !mDocShell) { NS_WARNING("Canvas element must be non-null or a docshell must be provided"); error.Throw(NS_ERROR_FAILURE); - return; + return false; } - nsIPresShell* presShell = GetPresShell(); + nsCOMPtr presShell = GetPresShell(); if (!presShell) { error.Throw(NS_ERROR_FAILURE); - return; + return false; } nsString usedFont; nsRefPtr sc = GetFontStyleContext(mCanvasElement, font, presShell, usedFont, error); if (!sc) { - return; + return false; } const nsStyleFont* fontStyle = sc->StyleFont(); @@ -3099,6 +3125,8 @@ CanvasRenderingContext2D::SetFont(const nsAString& font, CurrentState().fontFont.size = fontStyle->mSize; CurrentState().fontLanguage = fontStyle->mLanguage; CurrentState().fontExplicitLanguage = fontStyle->mExplicitLanguage; + + return true; } void @@ -3693,7 +3721,12 @@ CanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText, } gfxFontGroup* currentFontStyle = GetCurrentFontStyle(); - NS_ASSERTION(currentFontStyle, "font group is null"); + if (!currentFontStyle) { + return NS_ERROR_FAILURE; + } + + MOZ_ASSERT(!presShell->IsDestroying(), + "GetCurrentFontStyle() should have returned null if the presshell is being destroyed"); // ensure user font set is up to date currentFontStyle-> @@ -3891,8 +3924,9 @@ gfxFontGroup *CanvasRenderingContext2D::GetCurrentFontStyle() ErrorResult err; NS_NAMED_LITERAL_STRING(kDefaultFontStyle, "10px sans-serif"); static float kDefaultFontSize = 10.0; - SetFont(kDefaultFontStyle, err); - if (err.Failed()) { + nsCOMPtr presShell = GetPresShell(); + bool fontUpdated = SetFontInternal(kDefaultFontStyle, err); + if (err.Failed() || !fontUpdated) { gfxFontStyle style; style.size = kDefaultFontSize; CurrentState().fontGroup = @@ -3901,9 +3935,7 @@ gfxFontGroup *CanvasRenderingContext2D::GetCurrentFontStyle() nullptr); if (CurrentState().fontGroup) { CurrentState().font = kDefaultFontStyle; - - nsIPresShell* presShell = GetPresShell(); - if (presShell) { + if (presShell && !presShell->IsDestroying()) { CurrentState().fontGroup->SetTextPerfMetrics( presShell->GetPresContext()->GetTextPerfMetrics()); } @@ -3911,7 +3943,6 @@ gfxFontGroup *CanvasRenderingContext2D::GetCurrentFontStyle() NS_ERROR("Default canvas font is invalid"); } } - } return CurrentState().fontGroup; diff --git a/dom/canvas/CanvasRenderingContext2D.h b/dom/canvas/CanvasRenderingContext2D.h index b14fc2cc195d..893d4ddf0355 100644 --- a/dom/canvas/CanvasRenderingContext2D.h +++ b/dom/canvas/CanvasRenderingContext2D.h @@ -597,6 +597,10 @@ protected: nsTArray& aFilterChain, ErrorResult& error); + // Returns whether the font was successfully updated. + bool SetFontInternal(const nsAString& font, mozilla::ErrorResult& error); + + /** * Creates the error target, if it doesn't exist */ @@ -631,7 +635,7 @@ protected: */ RenderingMode EnsureTarget(RenderingMode aRenderMode = RenderingMode::DefaultBackendMode); - /* + /** * Disposes an old target and prepares to lazily create a new target. */ void ClearTarget(); @@ -867,10 +871,10 @@ protected: protected: gfxFontGroup *GetCurrentFontStyle(); - /* - * Implementation of the fillText, strokeText, and measure functions with - * the operation abstracted to a flag. - */ + /** + * Implementation of the fillText, strokeText, and measure functions with + * the operation abstracted to a flag. + */ nsresult DrawOrMeasureText(const nsAString& text, float x, float y, diff --git a/dom/html/HTMLCanvasElement.cpp b/dom/html/HTMLCanvasElement.cpp index 6e6e36ada435..214a53adae18 100644 --- a/dom/html/HTMLCanvasElement.cpp +++ b/dom/html/HTMLCanvasElement.cpp @@ -878,19 +878,21 @@ HTMLCanvasElement::UpdateContext(JSContext* aCx, JS::Handle aNewConte nsIntSize sz = GetWidthHeight(); - nsresult rv = mCurrentContext->SetIsOpaque(HasAttr(kNameSpaceID_None, nsGkAtoms::moz_opaque)); + nsCOMPtr currentContext = mCurrentContext; + + nsresult rv = currentContext->SetIsOpaque(HasAttr(kNameSpaceID_None, nsGkAtoms::moz_opaque)); if (NS_FAILED(rv)) { mCurrentContext = nullptr; return rv; } - rv = mCurrentContext->SetContextOptions(aCx, aNewContextOptions); + rv = currentContext->SetContextOptions(aCx, aNewContextOptions); if (NS_FAILED(rv)) { mCurrentContext = nullptr; return rv; } - rv = mCurrentContext->SetDimensions(sz.width, sz.height); + rv = currentContext->SetDimensions(sz.width, sz.height); if (NS_FAILED(rv)) { mCurrentContext = nullptr; return rv;