From 10a5ef8799806f593047d23b24e8377aa35e069f Mon Sep 17 00:00:00 2001 From: Andreea Pavel Date: Sat, 18 Jan 2020 21:47:49 +0200 Subject: [PATCH] Backed out 3 changesets (bug 1102584) for failing wpt at 2d.text.measure.actualBoundingBox.html Backed out changeset 947829830dd5 (bug 1102584) Backed out changeset 967170ab891c (bug 1102584) Backed out changeset 59069d4514d0 (bug 1102584) --- dom/canvas/CanvasRenderingContext2D.cpp | 144 ++++++------------ dom/canvas/CanvasRenderingContext2D.h | 8 +- dom/canvas/TextMetrics.h | 60 +------- dom/webidl/CanvasRenderingContext2D.webidl | 24 +-- modules/libpref/init/StaticPrefList.yaml | 20 --- ...2d.text.measure.actualBoundingBox.html.ini | 4 + .../2d.text.draw.baseline.hanging.html.ini | 3 +- .../meta/html/dom/idlharness.https.html.ini | 12 ++ 8 files changed, 76 insertions(+), 199 deletions(-) create mode 100644 testing/web-platform/meta/2dcontext/drawing-text-to-the-canvas/2d.text.measure.actualBoundingBox.html.ini diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index 429b26b040cf..b0d919ed1eaf 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -3346,25 +3346,29 @@ void CanvasRenderingContext2D::FillText(const nsAString& aText, double aX, double aY, const Optional& aMaxWidth, ErrorResult& aError) { - DebugOnly metrics = DrawOrMeasureText( - aText, aX, aY, aMaxWidth, TextDrawOperation::FILL, aError); - MOZ_ASSERT(!metrics); // drawing operation never returns TextMetrics + aError = DrawOrMeasureText(aText, aX, aY, aMaxWidth, TextDrawOperation::FILL, + nullptr); } void CanvasRenderingContext2D::StrokeText(const nsAString& aText, double aX, double aY, const Optional& aMaxWidth, ErrorResult& aError) { - DebugOnly metrics = DrawOrMeasureText( - aText, aX, aY, aMaxWidth, TextDrawOperation::STROKE, aError); - MOZ_ASSERT(!metrics); // drawing operation never returns TextMetrics + aError = DrawOrMeasureText(aText, aX, aY, aMaxWidth, + TextDrawOperation::STROKE, nullptr); } TextMetrics* CanvasRenderingContext2D::MeasureText(const nsAString& aRawText, ErrorResult& aError) { + float width; Optional maxWidth; - return DrawOrMeasureText(aRawText, 0, 0, maxWidth, TextDrawOperation::MEASURE, - aError); + aError = DrawOrMeasureText(aRawText, 0, 0, maxWidth, + TextDrawOperation::MEASURE, &width); + if (aError.Failed()) { + return nullptr; + } + + return new TextMetrics(width); } void CanvasRenderingContext2D::AddHitRegion(const HitRegionOptions& aOptions, @@ -3714,29 +3718,20 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor bool mDoMeasureBoundingBox; }; -TextMetrics* CanvasRenderingContext2D::DrawOrMeasureText( +nsresult CanvasRenderingContext2D::DrawOrMeasureText( const nsAString& aRawText, float aX, float aY, - const Optional& aMaxWidth, TextDrawOperation aOp, - ErrorResult& aError) { - // Approximated baselines. In an ideal world, we'd read the baseline info - // directly from the font (where available). Alas we currently lack - // that functionality. These numbers are best guesses and should - // suffice for now. Both are fractions of the em ascent/descent from the - // alphabetic baseline. - const double kHangingBaselineDefault = 0.8; // fraction of ascent - const double kIdeographicBaselineDefault = 0.5; // fraction of descent + const Optional& aMaxWidth, TextDrawOperation aOp, float* aWidth) { + nsresult rv; if (!mCanvasElement && !mDocShell) { NS_WARNING( "Canvas element must be non-null or a docshell must be provided"); - aError = NS_ERROR_FAILURE; - return nullptr; + return NS_ERROR_FAILURE; } RefPtr presShell = GetPresShell(); if (!presShell) { - aError = NS_ERROR_FAILURE; - return nullptr; + return NS_ERROR_FAILURE; } Document* document = presShell->GetDocument(); @@ -3760,8 +3755,7 @@ TextMetrics* CanvasRenderingContext2D::DrawOrMeasureText( // try to find the closest context canvasStyle = nsComputedDOMStyle::GetComputedStyle(mCanvasElement, nullptr); if (!canvasStyle) { - aError = NS_ERROR_FAILURE; - return nullptr; + return NS_ERROR_FAILURE; } isRTL = @@ -3774,14 +3768,12 @@ TextMetrics* CanvasRenderingContext2D::DrawOrMeasureText( // This is only needed to know if we can know the drawing bounding box easily. const bool doCalculateBounds = NeedToCalculateBounds(); if (presShell->IsDestroying()) { - aError = NS_ERROR_FAILURE; - return nullptr; + return NS_ERROR_FAILURE; } gfxFontGroup* currentFontStyle = GetCurrentFontStyle(); if (!currentFontStyle) { - aError = NS_ERROR_FAILURE; - return nullptr; + return NS_ERROR_FAILURE; } MOZ_ASSERT(!presShell->IsDestroying(), @@ -3795,23 +3787,14 @@ TextMetrics* CanvasRenderingContext2D::DrawOrMeasureText( currentFontStyle->SetUserFontSet(presContext->GetUserFontSet()); if (currentFontStyle->GetStyle()->size == 0.0F) { - aError = NS_OK; - if (aOp == TextDrawOperation::MEASURE) { - return new TextMetrics(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0); + if (aWidth) { + *aWidth = 0; } - return nullptr; + return NS_OK; } if (!IsFinite(aX) || !IsFinite(aY)) { - aError = NS_OK; - // This may not be correct - what should TextMetrics contain in the case of - // infinite width or height? - if (aOp == TextDrawOperation::MEASURE) { - return new TextMetrics(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0); - } - return nullptr; + return NS_OK; } CanvasBidiProcessor processor; @@ -3838,24 +3821,30 @@ TextMetrics* CanvasRenderingContext2D::DrawOrMeasureText( processor.mCtx = this; processor.mOp = aOp; processor.mBoundingBox = gfxRect(0, 0, 0, 0); - processor.mDoMeasureBoundingBox = doCalculateBounds || - !mIsEntireFrameInvalid || - aOp == TextDrawOperation::MEASURE; + processor.mDoMeasureBoundingBox = doCalculateBounds || !mIsEntireFrameInvalid; processor.mFontgrp = currentFontStyle; nscoord totalWidthCoord; // calls bidi algo twice since it needs the full text width and the // bounding boxes before rendering anything - aError = nsBidiPresUtils::ProcessText( + rv = nsBidiPresUtils::ProcessText( textToDraw.get(), textToDraw.Length(), isRTL ? NSBIDI_RTL : NSBIDI_LTR, presShell->GetPresContext(), processor, nsBidiPresUtils::MODE_MEASURE, nullptr, 0, &totalWidthCoord, &mBidiEngine); - if (aError.Failed()) { - return nullptr; + if (NS_FAILED(rv)) { + return rv; } float totalWidth = float(totalWidthCoord) / processor.mAppUnitsPerDevPixel; + if (aWidth) { + *aWidth = totalWidth; + } + + // if only measuring, don't need to do any more work + if (aOp == TextDrawOperation::MEASURE) { + return NS_OK; + } // offset pt.x based on text align gfxFloat anchorX; @@ -3871,8 +3860,7 @@ TextMetrics* CanvasRenderingContext2D::DrawOrMeasureText( anchorX = 1; } - float offsetX = anchorX * totalWidth; - processor.mPt.x -= offsetX; + processor.mPt.x -= anchorX * totalWidth; // offset pt.y (or pt.x, for vertical text) based on text baseline processor.mFontgrp @@ -3885,20 +3873,18 @@ TextMetrics* CanvasRenderingContext2D::DrawOrMeasureText( switch (state.textBaseline) { case TextBaseline::HANGING: - baselineAnchor = fontMetrics.emAscent * kHangingBaselineDefault; - break; + // fall through; best we can do with the information available case TextBaseline::TOP: baselineAnchor = fontMetrics.emAscent; break; case TextBaseline::MIDDLE: baselineAnchor = (fontMetrics.emAscent - fontMetrics.emDescent) * .5f; break; + case TextBaseline::IDEOGRAPHIC: + // fall through; best we can do with the information available case TextBaseline::ALPHABETIC: baselineAnchor = 0; break; - case TextBaseline::IDEOGRAPHIC: - baselineAnchor = -fontMetrics.emDescent * kIdeographicBaselineDefault; - break; case TextBaseline::BOTTOM: baselineAnchor = -fontMetrics.emDescent; break; @@ -3922,45 +3908,16 @@ TextMetrics* CanvasRenderingContext2D::DrawOrMeasureText( processor.mPt.y += baselineAnchor; } - // if only measuring, don't need to do any more work - if (aOp == TextDrawOperation::MEASURE) { - aError = NS_OK; - double actualBoundingBoxLeft = processor.mBoundingBox.X() - offsetX; - double actualBoundingBoxRight = processor.mBoundingBox.XMost() - offsetX; - double actualBoundingBoxAscent = - -processor.mBoundingBox.Y() - baselineAnchor; - double actualBoundingBoxDescent = - processor.mBoundingBox.YMost() + baselineAnchor; - double hangingBaseline = - fontMetrics.emAscent * kHangingBaselineDefault - baselineAnchor; - double ideographicBaseline = - -fontMetrics.emDescent * kIdeographicBaselineDefault - baselineAnchor; - return new TextMetrics( - totalWidth, actualBoundingBoxLeft, actualBoundingBoxRight, - fontMetrics.maxAscent - baselineAnchor, // fontBBAscent - fontMetrics.maxDescent + baselineAnchor, // fontBBDescent - actualBoundingBoxAscent, actualBoundingBoxDescent, - fontMetrics.emAscent - baselineAnchor, // emHeightAscent - -fontMetrics.emDescent - baselineAnchor, // emHeightDescent - hangingBaseline, - -baselineAnchor, // alphabeticBaseline - ideographicBaseline); - } - - // If we did not actually calculate bounds, set up a simple bounding box - // based on the text position and advance. - if (!doCalculateBounds) { - processor.mBoundingBox.width = totalWidth; - processor.mBoundingBox.MoveBy(gfxPoint(processor.mPt.x, processor.mPt.y)); - } + // correct bounding box to get it to be the correct size/position + processor.mBoundingBox.width = totalWidth; + processor.mBoundingBox.MoveBy(gfxPoint(processor.mPt.x, processor.mPt.y)); processor.mPt.x *= processor.mAppUnitsPerDevPixel; processor.mPt.y *= processor.mAppUnitsPerDevPixel; EnsureTarget(); if (!IsTargetValid()) { - aError = NS_ERROR_FAILURE; - return nullptr; + return NS_ERROR_FAILURE; } Matrix oldTransform = mTarget->GetTransform(); @@ -3986,26 +3943,21 @@ TextMetrics* CanvasRenderingContext2D::DrawOrMeasureText( // don't ever need to measure the bounding box twice processor.mDoMeasureBoundingBox = false; - aError = nsBidiPresUtils::ProcessText( + rv = nsBidiPresUtils::ProcessText( textToDraw.get(), textToDraw.Length(), isRTL ? NSBIDI_RTL : NSBIDI_LTR, presShell->GetPresContext(), processor, nsBidiPresUtils::MODE_DRAW, nullptr, 0, nullptr, &mBidiEngine); - if (aError.Failed()) { - return nullptr; - } - mTarget->SetTransform(oldTransform); if (aOp == CanvasRenderingContext2D::TextDrawOperation::FILL && !doCalculateBounds) { RedrawUser(boundingBox); - } else { - Redraw(); + return NS_OK; } - aError = NS_OK; - return nullptr; + Redraw(); + return NS_OK; } gfxFontGroup* CanvasRenderingContext2D::GetCurrentFontStyle() { diff --git a/dom/canvas/CanvasRenderingContext2D.h b/dom/canvas/CanvasRenderingContext2D.h index 6d250cdf58fc..b775774c8a1b 100644 --- a/dom/canvas/CanvasRenderingContext2D.h +++ b/dom/canvas/CanvasRenderingContext2D.h @@ -878,12 +878,10 @@ class CanvasRenderingContext2D final : public nsICanvasRenderingContextInternal, /** * Implementation of the fillText, strokeText, and measure functions with * the operation abstracted to a flag. - * Returns a TextMetrics object _only_ if the operation is measure; - * drawing operations (fill or stroke) always return nullptr. */ - TextMetrics* DrawOrMeasureText(const nsAString& aText, float aX, float aY, - const Optional& aMaxWidth, - TextDrawOperation aOp, ErrorResult& aError); + nsresult DrawOrMeasureText(const nsAString& aText, float aX, float aY, + const Optional& aMaxWidth, + TextDrawOperation aOp, float* aWidth); // A clip or a transform, recorded and restored in order. struct ClipState { diff --git a/dom/canvas/TextMetrics.h b/dom/canvas/TextMetrics.h index e079695b68fe..082db1fa6995 100644 --- a/dom/canvas/TextMetrics.h +++ b/dom/canvas/TextMetrics.h @@ -14,56 +14,13 @@ namespace dom { class TextMetrics final : public NonRefcountedDOMObject { public: - explicit TextMetrics(double aWidth, double aActualBoundingBoxLeft, - double aActualBoundingBoxRight, - double aFontBoundingBoxAscent, - double aFontBoundingBoxDescent, - double aActualBoundingBoxAscent, - double aActualBoundingBoxDescent, double aEmHeightAscent, - double aEmHeightDescent, double aHangingBaseline, - double aAlphabeticBaseline, double aIdeographicBaseline) - : width(aWidth), - actualBoundingBoxLeft(aActualBoundingBoxLeft), - actualBoundingBoxRight(aActualBoundingBoxRight), - fontBoundingBoxAscent(aFontBoundingBoxAscent), - fontBoundingBoxDescent(aFontBoundingBoxDescent), - actualBoundingBoxAscent(aActualBoundingBoxAscent), - actualBoundingBoxDescent(aActualBoundingBoxDescent), - emHeightAscent(aEmHeightAscent), - emHeightDescent(aEmHeightDescent), - hangingBaseline(aHangingBaseline), - alphabeticBaseline(aAlphabeticBaseline), - ideographicBaseline(aIdeographicBaseline) { + explicit TextMetrics(float aValue) : width(aValue) { MOZ_COUNT_CTOR(TextMetrics); } ~TextMetrics() { MOZ_COUNT_DTOR(TextMetrics); } - double Width() const { return width; } - - double ActualBoundingBoxLeft() const { return actualBoundingBoxLeft; } - - double ActualBoundingBoxRight() const { return actualBoundingBoxRight; } - - // y-direction - - double FontBoundingBoxAscent() const { return fontBoundingBoxAscent; } - - double FontBoundingBoxDescent() const { return fontBoundingBoxDescent; } - - double ActualBoundingBoxAscent() const { return actualBoundingBoxAscent; } - - double ActualBoundingBoxDescent() const { return actualBoundingBoxDescent; } - - double EmHeightAscent() const { return emHeightAscent; } - - double EmHeightDescent() const { return emHeightDescent; } - - double HangingBaseline() const { return hangingBaseline; } - - double AlphabeticBaseline() const { return alphabeticBaseline; } - - double IdeographicBaseline() const { return ideographicBaseline; } + float Width() const { return width; } bool WrapObject(JSContext* aCx, JS::Handle aGivenProto, JS::MutableHandle aReflector) { @@ -71,18 +28,7 @@ class TextMetrics final : public NonRefcountedDOMObject { } private: - double width; - double actualBoundingBoxLeft; - double actualBoundingBoxRight; - double fontBoundingBoxAscent; - double fontBoundingBoxDescent; - double actualBoundingBoxAscent; - double actualBoundingBoxDescent; - double emHeightAscent; - double emHeightDescent; - double hangingBaseline; - double alphabeticBaseline; - double ideographicBaseline; + float width; }; } // namespace dom diff --git a/dom/webidl/CanvasRenderingContext2D.webidl b/dom/webidl/CanvasRenderingContext2D.webidl index 705eb3a35208..25e2150e487c 100644 --- a/dom/webidl/CanvasRenderingContext2D.webidl +++ b/dom/webidl/CanvasRenderingContext2D.webidl @@ -358,38 +358,24 @@ interface TextMetrics { // x-direction readonly attribute double width; // advance width - // [experimental] actualBoundingBox* attributes - [Pref="dom.textMetrics.actualBoundingBox.enabled"] + /* + * NOT IMPLEMENTED YET + readonly attribute double actualBoundingBoxLeft; - [Pref="dom.textMetrics.actualBoundingBox.enabled"] readonly attribute double actualBoundingBoxRight; // y-direction - // [experimental] fontBoundingBox* attributes - [Pref="dom.textMetrics.fontBoundingBox.enabled"] readonly attribute double fontBoundingBoxAscent; - [Pref="dom.textMetrics.fontBoundingBox.enabled"] readonly attribute double fontBoundingBoxDescent; - - // [experimental] actualBoundingBox* attributes - [Pref="dom.textMetrics.actualBoundingBox.enabled"] readonly attribute double actualBoundingBoxAscent; - [Pref="dom.textMetrics.actualBoundingBox.enabled"] readonly attribute double actualBoundingBoxDescent; - - // [experimental] emHeight* attributes - [Pref="dom.textMetrics.emHeight.enabled"] readonly attribute double emHeightAscent; - [Pref="dom.textMetrics.emHeight.enabled"] readonly attribute double emHeightDescent; - - // [experimental] *Baseline attributes - [Pref="dom.textMetrics.baselines.enabled"] readonly attribute double hangingBaseline; - [Pref="dom.textMetrics.baselines.enabled"] readonly attribute double alphabeticBaseline; - [Pref="dom.textMetrics.baselines.enabled"] readonly attribute double ideographicBaseline; + */ + }; [Pref="canvas.path.enabled", diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index 3c543070942c..1dd7147d39bd 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -2392,26 +2392,6 @@ value: false mirror: always -- name: dom.textMetrics.actualBoundingBox.enabled - type: bool - value: true - mirror: always - -- name: dom.textMetrics.baselines.enabled - type: bool - value: false - mirror: always - -- name: dom.textMetrics.emHeight.enabled - type: bool - value: false - mirror: always - -- name: dom.textMetrics.fontBoundingBox.enabled - type: bool - value: false - mirror: always - # Time (in ms) that it takes to regenerate 1ms. - name: dom.timeout.background_budget_regeneration_rate type: int32_t diff --git a/testing/web-platform/meta/2dcontext/drawing-text-to-the-canvas/2d.text.measure.actualBoundingBox.html.ini b/testing/web-platform/meta/2dcontext/drawing-text-to-the-canvas/2d.text.measure.actualBoundingBox.html.ini new file mode 100644 index 000000000000..93a00d9d776a --- /dev/null +++ b/testing/web-platform/meta/2dcontext/drawing-text-to-the-canvas/2d.text.measure.actualBoundingBox.html.ini @@ -0,0 +1,4 @@ +[2d.text.measure.actualBoundingBox.html] + [Testing actualBoundingBox] + expected: FAIL + diff --git a/testing/web-platform/meta/2dcontext/text-styles/2d.text.draw.baseline.hanging.html.ini b/testing/web-platform/meta/2dcontext/text-styles/2d.text.draw.baseline.hanging.html.ini index 06daa40c892f..4b933de9c99d 100644 --- a/testing/web-platform/meta/2dcontext/text-styles/2d.text.draw.baseline.hanging.html.ini +++ b/testing/web-platform/meta/2dcontext/text-styles/2d.text.draw.baseline.hanging.html.ini @@ -1,5 +1,4 @@ [2d.text.draw.baseline.hanging.html] [Canvas test: 2d.text.draw.baseline.hanging] - expected: - if os == "android": FAIL + expected: FAIL diff --git a/testing/web-platform/meta/html/dom/idlharness.https.html.ini b/testing/web-platform/meta/html/dom/idlharness.https.html.ini index bfd55abb450c..a575b5176748 100644 --- a/testing/web-platform/meta/html/dom/idlharness.https.html.ini +++ b/testing/web-platform/meta/html/dom/idlharness.https.html.ini @@ -189,6 +189,9 @@ prefs: [dom.security.featurePolicy.enabled:true, dom.security.featurePolicy.expe [Navigator interface: calling unregisterProtocolHandler(DOMString, USVString) on window.navigator with too few arguments must throw TypeError] expected: FAIL + [TextMetrics interface: attribute actualBoundingBoxAscent] + expected: FAIL + [OffscreenCanvas interface: existence and properties of interface prototype object] expected: FAIL @@ -327,12 +330,18 @@ prefs: [dom.security.featurePolicy.enabled:true, dom.security.featurePolicy.expe [Stringification of window.applicationCache] expected: FAIL + [TextMetrics interface: attribute actualBoundingBoxDescent] + expected: FAIL + [OffscreenCanvasRenderingContext2D interface: operation isPointInPath(unrestricted double, unrestricted double, CanvasFillRule)] expected: FAIL [VideoTrack interface: attribute language] expected: FAIL + [TextMetrics interface: attribute actualBoundingBoxLeft] + expected: FAIL + [VideoTrackList interface: attribute onremovetrack] expected: FAIL @@ -501,6 +510,9 @@ prefs: [dom.security.featurePolicy.enabled:true, dom.security.featurePolicy.expe [External interface: operation IsSearchProviderInstalled()] expected: FAIL + [TextMetrics interface: attribute actualBoundingBoxRight] + expected: FAIL + [SVGElement interface: attribute nonce] expected: FAIL