зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1778910 - Hook up rendering support for canvas2d fontVariantCaps, and add WPT reftests. r=gfx-reviewers,lsalzman
The behavior in some of these cases is open to debate, as the spec is quite unclear; see https://github.com/whatwg/html/issues/8103. What I've implemented here gives the same rendering result as Chrome for these tests, so hopefully we can get this clarified in the spec as well. Differential Revision: https://phabricator.services.mozilla.com/D182567
This commit is contained in:
Родитель
c5a0f7995c
Коммит
6c6d97166b
|
@ -3693,6 +3693,10 @@ void CanvasRenderingContext2D::SetFont(const nsACString& aFont,
|
|||
return;
|
||||
}
|
||||
|
||||
// Setting the font attribute magically resets fontVariantCaps to normal.
|
||||
// (spec unclear, cf. https://github.com/whatwg/html/issues/8103)
|
||||
SetFontVariantCaps(CanvasFontVariantCaps::Normal);
|
||||
|
||||
// If letterSpacing or wordSpacing is present, recompute to account for
|
||||
// changes to font-relative dimensions.
|
||||
UpdateSpacing();
|
||||
|
@ -3752,6 +3756,38 @@ bool CanvasRenderingContext2D::SetFontInternal(const nsACString& aFont,
|
|||
|
||||
resizedFont.kerning = CanvasToGfx(CurrentState().fontKerning);
|
||||
|
||||
// fontVariantCaps handling: if fontVariantCaps is not 'normal', apply it;
|
||||
// if it is, then use the smallCaps boolean from the shorthand.
|
||||
// XXX(jfkthame) The interaction between the shorthand and the separate attr
|
||||
// here is not clearly spec'd, and we may want to reconsider it (or revise
|
||||
// the available values); see https://github.com/whatwg/html/issues/8103.
|
||||
switch (CurrentState().fontVariantCaps) {
|
||||
case CanvasFontVariantCaps::Normal:
|
||||
// Leave whatever the shorthand set.
|
||||
break;
|
||||
case CanvasFontVariantCaps::Small_caps:
|
||||
resizedFont.variantCaps = NS_FONT_VARIANT_CAPS_SMALLCAPS;
|
||||
break;
|
||||
case CanvasFontVariantCaps::All_small_caps:
|
||||
resizedFont.variantCaps = NS_FONT_VARIANT_CAPS_ALLSMALL;
|
||||
break;
|
||||
case CanvasFontVariantCaps::Petite_caps:
|
||||
resizedFont.variantCaps = NS_FONT_VARIANT_CAPS_PETITECAPS;
|
||||
break;
|
||||
case CanvasFontVariantCaps::All_petite_caps:
|
||||
resizedFont.variantCaps = NS_FONT_VARIANT_CAPS_ALLPETITE;
|
||||
break;
|
||||
case CanvasFontVariantCaps::Unicase:
|
||||
resizedFont.variantCaps = NS_FONT_VARIANT_CAPS_UNICASE;
|
||||
break;
|
||||
case CanvasFontVariantCaps::Titling_caps:
|
||||
resizedFont.variantCaps = NS_FONT_VARIANT_CAPS_TITLING;
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("unknown caps value");
|
||||
break;
|
||||
}
|
||||
|
||||
c->Document()->FlushUserFontSet();
|
||||
|
||||
nsFontMetrics::Params params;
|
||||
|
@ -3857,8 +3893,42 @@ bool CanvasRenderingContext2D::SetFontInternalDisconnected(
|
|||
}
|
||||
|
||||
fontStyle.size = QuantizeFontSize(size);
|
||||
fontStyle.variantCaps =
|
||||
smallCaps ? NS_FONT_VARIANT_CAPS_SMALLCAPS : NS_FONT_VARIANT_CAPS_NORMAL;
|
||||
|
||||
// fontVariantCaps handling: if fontVariantCaps is not 'normal', apply it;
|
||||
// if it is, then use the smallCaps boolean from the shorthand.
|
||||
// XXX(jfkthame) The interaction between the shorthand and the separate attr
|
||||
// here is not clearly spec'd, and we may want to reconsider it (or revise
|
||||
// the available values); see https://github.com/whatwg/html/issues/8103.
|
||||
switch (CurrentState().fontVariantCaps) {
|
||||
case CanvasFontVariantCaps::Normal:
|
||||
fontStyle.variantCaps = smallCaps ? NS_FONT_VARIANT_CAPS_SMALLCAPS
|
||||
: NS_FONT_VARIANT_CAPS_NORMAL;
|
||||
break;
|
||||
case CanvasFontVariantCaps::Small_caps:
|
||||
fontStyle.variantCaps = NS_FONT_VARIANT_CAPS_SMALLCAPS;
|
||||
break;
|
||||
case CanvasFontVariantCaps::All_small_caps:
|
||||
fontStyle.variantCaps = NS_FONT_VARIANT_CAPS_ALLSMALL;
|
||||
break;
|
||||
case CanvasFontVariantCaps::Petite_caps:
|
||||
fontStyle.variantCaps = NS_FONT_VARIANT_CAPS_PETITECAPS;
|
||||
break;
|
||||
case CanvasFontVariantCaps::All_petite_caps:
|
||||
fontStyle.variantCaps = NS_FONT_VARIANT_CAPS_ALLPETITE;
|
||||
break;
|
||||
case CanvasFontVariantCaps::Unicase:
|
||||
fontStyle.variantCaps = NS_FONT_VARIANT_CAPS_UNICASE;
|
||||
break;
|
||||
case CanvasFontVariantCaps::Titling_caps:
|
||||
fontStyle.variantCaps = NS_FONT_VARIANT_CAPS_TITLING;
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("unknown caps value");
|
||||
break;
|
||||
}
|
||||
// If variantCaps is set, we need to disable a gfxFont fast-path.
|
||||
fontStyle.noFallbackVariantFeatures =
|
||||
(fontStyle.variantCaps == NS_FONT_VARIANT_CAPS_NORMAL);
|
||||
|
||||
// Set the kerning feature, if required by the fontKerning attribute.
|
||||
gfxFontFeature setting{TRUETYPE_TAG('k', 'e', 'r', 'n'), 0};
|
||||
|
@ -3907,6 +3977,7 @@ bool CanvasRenderingContext2D::SetFontInternalDisconnected(
|
|||
SerializeFontForCanvas(list, fontStyle, CurrentState().font);
|
||||
CurrentState().fontFont = nsFont(StyleFontFamily{list, false, false},
|
||||
StyleCSSPixelLength::FromPixels(size));
|
||||
CurrentState().fontFont.variantCaps = fontStyle.variantCaps;
|
||||
CurrentState().fontLanguage = nullptr;
|
||||
CurrentState().fontExplicitLanguage = false;
|
||||
return true;
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>HTML Canvas Test: the 'fontVariantCaps' property</title>
|
||||
<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-fontvariantcaps">
|
||||
<link rel="match" href="reference/fontVariantCaps-1-ref.html">
|
||||
<meta name="assert" content="text rendering respects the fontVariantCaps property">
|
||||
|
||||
<canvas id="c"></canvas>
|
||||
|
||||
<script>
|
||||
let ctx = c.getContext("2d");
|
||||
ctx.font = "32px serif";
|
||||
ctx.fontVariantCaps = "small-caps";
|
||||
// This should render the same as font = "small-caps 32px serif".
|
||||
ctx.fillText("Hello World", 20, 100);
|
||||
</script>
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>HTML Canvas Test: the 'fontVariantCaps' property</title>
|
||||
<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-fontvariantcaps">
|
||||
<link rel="mismatch" href="reference/fontVariantCaps-2-ref.html">
|
||||
<meta name="assert" content="text rendering respects the fontVariantCaps property">
|
||||
|
||||
<canvas id="c"></canvas>
|
||||
|
||||
<script>
|
||||
let ctx = c.getContext("2d");
|
||||
ctx.font = "small-caps 32px serif";
|
||||
// "mismatch" test, to verify that small-caps does change the rendering.
|
||||
ctx.fillText("Hello World", 20, 100);
|
||||
</script>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>HTML Canvas Test: the 'fontVariantCaps' property</title>
|
||||
<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-fontvariantcaps">
|
||||
<link rel="match" href="reference/fontVariantCaps-3-ref.html">
|
||||
<meta name="assert" content="text rendering respects the fontVariantCaps property">
|
||||
|
||||
<canvas id="c"></canvas>
|
||||
|
||||
<script>
|
||||
let ctx = c.getContext("2d");
|
||||
ctx.font = "32px serif";
|
||||
ctx.fontVariantCaps = "all-small-caps";
|
||||
// This should render the same as using font = "small-caps 32px serif"
|
||||
// with all the underlying text in lowercase.
|
||||
ctx.fillText("Hello World", 20, 100);
|
||||
</script>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>HTML Canvas Test: the 'fontVariantCaps' property</title>
|
||||
<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-fontvariantcaps">
|
||||
<link rel="match" href="reference/fontVariantCaps-3-ref.html">
|
||||
<meta name="assert" content="text rendering respects the fontVariantCaps property">
|
||||
|
||||
<canvas id="c"></canvas>
|
||||
|
||||
<script>
|
||||
let ctx = c.getContext("2d");
|
||||
ctx.font = "small-caps 32px serif";
|
||||
// fontVariantCaps overrides the small-caps setting from the font attribute
|
||||
// (spec unclear, cf. https://github.com/whatwg/html/issues/8103)
|
||||
ctx.fontVariantCaps = "all-small-caps";
|
||||
ctx.fillText("Hello World", 20, 100);
|
||||
</script>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>HTML Canvas Test: the 'fontVariantCaps' property</title>
|
||||
<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-fontvariantcaps">
|
||||
<link rel="match" href="reference/fontVariantCaps-1-ref.html">
|
||||
<meta name="assert" content="text rendering respects the fontVariantCaps property">
|
||||
|
||||
<canvas id="c"></canvas>
|
||||
|
||||
<script>
|
||||
let ctx = c.getContext("2d");
|
||||
ctx.font = "small-caps 32px serif";
|
||||
// fontVariantCaps 'normal' does not override the setting from the font attribute.
|
||||
// (spec unclear, cf. https://github.com/whatwg/html/issues/8103)
|
||||
ctx.fontVariantCaps = "normal";
|
||||
ctx.fillText("Hello World", 20, 100);
|
||||
</script>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>HTML Canvas Test: the 'fontVariantCaps' property</title>
|
||||
<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-fontvariantcaps">
|
||||
<link rel="match" href="reference/fontVariantCaps-2-ref.html">
|
||||
<meta name="assert" content="text rendering respects the fontVariantCaps property">
|
||||
|
||||
<canvas id="c"></canvas>
|
||||
|
||||
<script>
|
||||
let ctx = c.getContext("2d");
|
||||
// fontVariantCaps is reset when the font attribute is set.
|
||||
// (spec unclear, cf. https://github.com/whatwg/html/issues/8103)
|
||||
ctx.fontVariantCaps = "all-small-caps";
|
||||
ctx.font = "32px serif";
|
||||
ctx.fillText("Hello World", 20, 100);
|
||||
</script>
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>HTML Canvas reference</title>
|
||||
<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
|
||||
|
||||
<canvas id="c"></canvas>
|
||||
|
||||
<script>
|
||||
let ctx = c.getContext("2d");
|
||||
ctx.font = "small-caps 32px serif";
|
||||
ctx.fillText("Hello World", 20, 100);
|
||||
</script>
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>HTML Canvas reference</title>
|
||||
<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
|
||||
|
||||
<canvas id="c"></canvas>
|
||||
|
||||
<script>
|
||||
let ctx = c.getContext("2d");
|
||||
ctx.font = "32px serif";
|
||||
ctx.fillText("Hello World", 20, 100);
|
||||
</script>
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>HTML Canvas reference</title>
|
||||
<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
|
||||
|
||||
<canvas id="c"></canvas>
|
||||
|
||||
<script>
|
||||
let ctx = c.getContext("2d");
|
||||
ctx.font = "small-caps 32px serif";
|
||||
ctx.fillText("hello world", 20, 100);
|
||||
</script>
|
Загрузка…
Ссылка в новой задаче