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)
This commit is contained in:
Andreea Pavel 2020-01-18 21:47:49 +02:00
Родитель cef90d7b6e
Коммит 10a5ef8799
8 изменённых файлов: 76 добавлений и 199 удалений

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

@ -3346,25 +3346,29 @@ void CanvasRenderingContext2D::FillText(const nsAString& aText, double aX,
double aY,
const Optional<double>& aMaxWidth,
ErrorResult& aError) {
DebugOnly<TextMetrics*> 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<double>& aMaxWidth,
ErrorResult& aError) {
DebugOnly<TextMetrics*> 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<double> 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<double>& 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<double>& 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> 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() {

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

@ -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<double>& aMaxWidth,
TextDrawOperation aOp, ErrorResult& aError);
nsresult DrawOrMeasureText(const nsAString& aText, float aX, float aY,
const Optional<double>& aMaxWidth,
TextDrawOperation aOp, float* aWidth);
// A clip or a transform, recorded and restored in order.
struct ClipState {

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

@ -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<JSObject*> aGivenProto,
JS::MutableHandle<JSObject*> 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

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

@ -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",

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

@ -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

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

@ -0,0 +1,4 @@
[2d.text.measure.actualBoundingBox.html]
[Testing actualBoundingBox]
expected: FAIL

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

@ -1,5 +1,4 @@
[2d.text.draw.baseline.hanging.html]
[Canvas test: 2d.text.draw.baseline.hanging]
expected:
if os == "android": FAIL
expected: FAIL

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

@ -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