Changeset 270102 in webkit
- Timestamp:
- Nov 20, 2020 3:40:06 AM (3 years ago)
- Location:
- trunk
- Files:
-
- 23 added
- 87 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r270101 r270102 1 2020-11-20 Chris Lord <clord@igalia.com> 2 3 Enable font functions on OffscreenCanvas for main-thread 4 https://bugs.webkit.org/show_bug.cgi?id=219088 5 6 Reviewed by Simon Fraser. 7 8 Enable running OffscreenCanvas text tests. 9 10 * platform/glib/TestExpectations: 11 1 12 2020-11-20 Youenn Fablet <youenn@apple.com> 2 13 -
trunk/LayoutTests/imported/w3c/ChangeLog
r270101 r270102 1 2020-11-20 Chris Lord <clord@igalia.com> 2 3 Enable font functions on OffscreenCanvas for main-thread 4 https://bugs.webkit.org/show_bug.cgi?id=219088 5 6 Reviewed by Simon Fraser. 7 8 Update test expectations for OffscreenCanvas text tests and add where 9 they were missing. 10 11 * web-platform-tests/html/canvas/offscreen/text/*: 12 1 13 2020-11-20 Youenn Fablet <youenn@apple.com> 2 14 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.align.default-expected.txt
r262615 r270102 2 2 3 3 4 FAIL OffscreenCanvas test: 2d.text.align.default assert_equals: ctx.textAlign === 'start' (got [undefined], expected start[string]) expected (string) "start" but got (undefined) undefined 4 PASS OffscreenCanvas test: 2d.text.align.default 5 5 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.align.default.worker-expected.txt
r262615 r270102 1 1 2 FAIL 2d assert_equals: ctx.textAlign === 'start' (got [undefined], expected start[string]) expected (string) "start" but got (undefined) undefined2 PASS 2d 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.align.invalid-expected.txt
r262615 r270102 2 2 3 3 4 FAIL OffscreenCanvas test: 2d.text.align.invalid assert_equals: ctx.textAlign === 'start' (got bogus[string], expected start[string]) expected "start" but got "bogus" 4 PASS OffscreenCanvas test: 2d.text.align.invalid 5 5 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.align.invalid.worker-expected.txt
r262615 r270102 1 1 2 FAIL 2d assert_equals: ctx.textAlign === 'start' (got bogus[string], expected start[string]) expected "start" but got "bogus" 2 PASS 2d 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.baseline.default-expected.txt
r262615 r270102 2 2 3 3 4 FAIL OffscreenCanvas test: 2d.text.baseline.default assert_equals: ctx.textBaseline === 'alphabetic' (got [undefined], expected alphabetic[string]) expected (string) "alphabetic" but got (undefined) undefined 4 PASS OffscreenCanvas test: 2d.text.baseline.default 5 5 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.baseline.default.worker-expected.txt
r262615 r270102 1 1 2 FAIL 2d assert_equals: ctx.textBaseline === 'alphabetic' (got [undefined], expected alphabetic[string]) expected (string) "alphabetic" but got (undefined) undefined2 PASS 2d 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.baseline.invalid-expected.txt
r262615 r270102 2 2 3 3 4 FAIL OffscreenCanvas test: 2d.text.baseline.invalid assert_equals: ctx.textBaseline === 'top' (got bogus[string], expected top[string]) expected "top" but got "bogus" 4 PASS OffscreenCanvas test: 2d.text.baseline.invalid 5 5 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.baseline.invalid.worker-expected.txt
r262615 r270102 1 1 2 FAIL 2d assert_equals: ctx.textBaseline === 'top' (got bogus[string], expected top[string]) expected "top" but got "bogus" 2 PASS 2d 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.align.center.worker-expected.txt
r267646 r270102 1 1 2 PASS textAlign center is the center of the em squares (not the bounding box) 2 FAIL textAlign center is the center of the em squares (not the bounding box) Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.align.end.ltr.worker-expected.txt
r267646 r270102 1 1 2 PASS textAlign end with ltr is the right edge2 FAIL textAlign end with ltr is the right edge Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.align.end.rtl.worker-expected.txt
r267646 r270102 1 1 2 PASS textAlign end with rtl is the left edge2 FAIL textAlign end with rtl is the left edge Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.align.left.worker-expected.txt
r267646 r270102 1 1 2 PASS textAlign left is the left of the first em square (not the bounding box) 2 FAIL textAlign left is the left of the first em square (not the bounding box) Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.align.right.worker-expected.txt
r267646 r270102 1 1 2 PASS textAlign right is the right of the last em square (not the bounding box) 2 FAIL textAlign right is the right of the last em square (not the bounding box) Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.align.start.ltr.worker-expected.txt
r267646 r270102 1 1 2 PASS textAlign start with ltr is the left edge2 FAIL textAlign start with ltr is the left edge Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.align.start.rtl.worker-expected.txt
r267646 r270102 1 1 2 PASS textAlign start with rtl is the right edge2 FAIL textAlign start with rtl is the right edge Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.baseline.alphabetic.worker-expected.txt
r267646 r270102 1 1 2 PASS 2d 2 FAIL 2d Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.baseline.bottom-expected.txt
r267646 r270102 4 4 5 5 6 PASS textBaseline bottom is the bottom of the em square (not the bounding box) 6 FAIL textBaseline bottom is the bottom of the em square (not the bounding box) assert_approx_equals: Red channel of the pixel at (25, 25) expected 0 +/- 2 but got 255 7 7 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.baseline.bottom.worker-expected.txt
r267646 r270102 1 1 2 PASS textBaseline bottom is the bottom of the em square (not the bounding box) 2 FAIL textBaseline bottom is the bottom of the em square (not the bounding box) Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.baseline.hanging-expected.txt
r267646 r270102 2 2 3 3 4 PASS OffscreenCanvas test: 2d.text.draw.baseline.hanging 4 FAIL OffscreenCanvas test: 2d.text.draw.baseline.hanging assert_approx_equals: Red channel of the pixel at (5, 5) expected 0 +/- 2 but got 255 5 5 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.baseline.hanging.worker-expected.txt
r267646 r270102 1 1 2 PASS 2d 2 FAIL 2d Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.baseline.ideographic-expected.txt
r267646 r270102 2 2 3 3 4 PASS OffscreenCanvas test: 2d.text.draw.baseline.ideographic 4 FAIL OffscreenCanvas test: 2d.text.draw.baseline.ideographic assert_approx_equals: Red channel of the pixel at (5, 5) expected 0 +/- 2 but got 255 5 5 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.baseline.ideographic.worker-expected.txt
r267646 r270102 1 1 2 PASS 2d 2 FAIL 2d Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.baseline.middle-expected.txt
r267646 r270102 4 4 5 5 6 PASS textBaseline middle is the middle of the em square (not the bounding box) 6 FAIL textBaseline middle is the middle of the em square (not the bounding box) assert_approx_equals: Red channel of the pixel at (5, 5) expected 0 +/- 2 but got 255 7 7 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.baseline.middle.worker-expected.txt
r267646 r270102 1 1 2 PASS textBaseline middle is the middle of the em square (not the bounding box) 2 FAIL textBaseline middle is the middle of the em square (not the bounding box) Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.baseline.top-expected.txt
r267646 r270102 4 4 5 5 6 PASS textBaseline top is the top of the em square (not the bounding box) 6 FAIL textBaseline top is the top of the em square (not the bounding box) assert_approx_equals: Red channel of the pixel at (5, 5) expected 0 +/- 2 but got 255 7 7 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.baseline.top.worker-expected.txt
r267646 r270102 1 1 2 PASS textBaseline top is the top of the em square (not the bounding box) 2 FAIL textBaseline top is the top of the em square (not the bounding box) Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.fill.basic-manual.worker-expected.txt
r262615 r270102 1 1 2 FAIL fillText draws filled text ctx.fillText is not a function. (In 'ctx.fillText('PASS', 5, 35)', 'ctx.fillText' is undefined) 2 PASS fillText draws filled text 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.NaN-expected.txt
r262615 r270102 4 4 5 5 6 FAIL fillText handles maxWidth correctly ctx.fillText is not a function. (In 'ctx.fillText('fail fail fail fail fail', 5, 35, NaN)', 'ctx.fillText' is undefined) 6 PASS fillText handles maxWidth correctly 7 7 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.NaN.worker-expected.txt
r262615 r270102 1 1 2 FAIL fillText handles maxWidth correctly ctx.fillText is not a function. (In 'ctx.fillText('fail fail fail fail fail', 5, 35, NaN)', 'ctx.fillText' is undefined) 2 PASS fillText handles maxWidth correctly 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.bound.worker-expected.txt
r267646 r270102 1 1 2 PASS fillText handles maxWidth based on line size, not bounding box size2 FAIL fillText handles maxWidth based on line size, not bounding box size Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.fontface.worker-expected.txt
r267646 r270102 1 1 2 PASS fillText works on @font-face fonts 2 FAIL fillText works on @font-face fonts Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.large-manual.worker-expected.txt
r262615 r270102 1 1 2 FAIL fillText handles maxWidth correctly ctx.fillText is not a function. (In 'ctx.fillText('PASS', 5, 35, 200)', 'ctx.fillText' is undefined) 2 PASS fillText handles maxWidth correctly 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.negative-expected.txt
r262615 r270102 4 4 5 5 6 FAIL fillText handles maxWidth correctly ctx.fillText is not a function. (In 'ctx.fillText('fail fail fail fail fail', 5, 35, -1)', 'ctx.fillText' is undefined) 6 PASS fillText handles maxWidth correctly 7 7 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.negative.worker-expected.txt
r262615 r270102 1 1 2 FAIL fillText handles maxWidth correctly ctx.fillText is not a function. (In 'ctx.fillText('fail fail fail fail fail', 5, 35, -1)', 'ctx.fillText' is undefined) 2 PASS fillText handles maxWidth correctly 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.small-expected.txt
r262615 r270102 4 4 5 5 6 FAIL fillText handles maxWidth correctly ctx.fillText is not a function. (In 'ctx.fillText('fail fail fail fail fail', -100, 35, 90)', 'ctx.fillText' is undefined) 6 PASS fillText handles maxWidth correctly 7 7 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.small.worker-expected.txt
r262615 r270102 1 1 2 FAIL fillText handles maxWidth correctly ctx.fillText is not a function. (In 'ctx.fillText('fail fail fail fail fail', -100, 35, 90)', 'ctx.fillText' is undefined) 2 PASS fillText handles maxWidth correctly 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.zero-expected.txt
r262615 r270102 4 4 5 5 6 FAIL fillText handles maxWidth correctly ctx.fillText is not a function. (In 'ctx.fillText('fail fail fail fail fail', 5, 35, 0)', 'ctx.fillText' is undefined) 6 PASS fillText handles maxWidth correctly 7 7 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.zero.worker-expected.txt
r262615 r270102 1 1 2 FAIL fillText handles maxWidth correctly ctx.fillText is not a function. (In 'ctx.fillText('fail fail fail fail fail', 5, 35, 0)', 'ctx.fillText' is undefined) 2 PASS fillText handles maxWidth correctly 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.fill.rtl-manual.worker-expected.txt
r262615 r270102 1 1 2 FAIL fillText respects Right-To-Left Override characters ctx.fillText is not a function. (In 'ctx.fillText('\u202eFAIL \xa0 \xa0 SSAP', 5, 35)', 'ctx.fillText' is undefined) 2 PASS fillText respects Right-To-Left Override characters 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.fill.unaffected-expected.txt
r262615 r270102 4 4 5 5 6 FAIL fillText does not start a new path or subpath ctx.fillText is not a function. (In 'ctx.fillText('FAIL', 5, 35)', 'ctx.fillText' is undefined) 6 PASS fillText does not start a new path or subpath 7 7 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.fill.unaffected.worker-expected.txt
r262615 r270102 1 1 2 FAIL fillText does not start a new path or subpath ctx.fillText is not a function. (In 'ctx.fillText('FAIL', 5, 35)', 'ctx.fillText' is undefined) 2 PASS fillText does not start a new path or subpath 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.fontface.notinpage.worker-expected.txt
r267646 r270102 1 1 2 PASS @font-face fonts should work even if they are not used in the page2 FAIL @font-face fonts should work even if they are not used in the page Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.fontface.repeat-expected.txt
r262615 r270102 4 4 5 5 6 FAIL Draw with the font immediately, then wait a bit until and draw again. (This crashes some version of WebKit.) ctx.fillText is not a function. (In 'ctx.fillText('AA', 0, 50)', 'ctx.fillText' is undefined)6 PASS Draw with the font immediately, then wait a bit until and draw again. (This crashes some version of WebKit.) 7 7 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.fontface.repeat.worker-expected.txt
r262615 r270102 1 1 2 FAIL Draw with the font immediately, then wait a bit until and draw again. (This crashes some version of WebKit.) ctx.fillText is not a function. (In 'ctx.fillText('AA', 0, 50)', 'ctx.fillText' is undefined)2 FAIL Draw with the font immediately, then wait a bit until and draw again. (This crashes some version of WebKit.) Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.fontface.worker-expected.txt
r267646 r270102 1 1 2 PASS 2d 2 FAIL 2d Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.kern.consistent-manual.worker-expected.txt
r262615 r270102 1 1 2 FAIL Stroked and filled text should have exactly the same kerning so it overlaps ctx.fillText is not a function. (In 'ctx.fillText('VAVAVAVAVAVAVA', -50, 25)', 'ctx.fillText' is undefined) 2 PASS Stroked and filled text should have exactly the same kerning so it overlaps 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.space.basic.worker-expected.txt
r267646 r270102 1 1 2 PASS U+0020 is rendered the correct size (1em wide) 2 FAIL U+0020 is rendered the correct size (1em wide) Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.end-expected.txt
r267646 r270102 4 4 5 5 6 PASS Space characters at the end of a line are collapsed (per CSS) 6 FAIL Space characters at the end of a line are collapsed (per CSS) assert_approx_equals: Red channel of the pixel at (75, 25) expected 0 +/- 2 but got 255 7 7 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.end.worker-expected.txt
r267646 r270102 1 1 2 PASS Space characters at the end of a line are collapsed (per CSS) 2 FAIL Space characters at the end of a line are collapsed (per CSS) Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.nonspace.worker-expected.txt
r267646 r270102 1 1 2 PASS Non-space characters are not converted to U+0020 and collapsed 2 FAIL Non-space characters are not converted to U+0020 and collapsed Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.other-expected.txt
r267646 r270102 4 4 5 5 6 PASS Space characters are converted to U+0020, and collapsed (per CSS) 6 FAIL Space characters are converted to U+0020, and collapsed (per CSS) assert_approx_equals: Red channel of the pixel at (25, 25) expected 0 +/- 2 but got 255 7 7 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.other.worker-expected.txt
r267646 r270102 1 1 2 PASS Space characters are converted to U+0020, and collapsed (per CSS) 2 FAIL Space characters are converted to U+0020, and collapsed (per CSS) Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.space-expected.txt
r267646 r270102 4 4 5 5 6 PASS Space characters are converted to U+0020, and collapsed (per CSS) 6 FAIL Space characters are converted to U+0020, and collapsed (per CSS) assert_approx_equals: Red channel of the pixel at (25, 25) expected 0 +/- 2 but got 255 7 7 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.space.worker-expected.txt
r267646 r270102 1 1 2 PASS Space characters are converted to U+0020, and collapsed (per CSS) 2 FAIL Space characters are converted to U+0020, and collapsed (per CSS) Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.start-expected.txt
r267646 r270102 4 4 5 5 6 PASS Space characters at the start of a line are collapsed (per CSS) 6 FAIL Space characters at the start of a line are collapsed (per CSS) assert_approx_equals: Red channel of the pixel at (25, 25) expected 0 +/- 2 but got 255 7 7 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.start.worker-expected.txt
r267646 r270102 1 1 2 PASS Space characters at the start of a line are collapsed (per CSS) 2 FAIL Space characters at the start of a line are collapsed (per CSS) Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.stroke.basic-manual.worker-expected.txt
r262615 r270102 1 1 2 FAIL strokeText draws stroked text ctx.strokeText is not a function. (In 'ctx.strokeText('PASS', 5, 35)', 'ctx.strokeText' is undefined) 2 PASS strokeText draws stroked text 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.stroke.unaffected-expected.txt
r262615 r270102 4 4 5 5 6 FAIL strokeText does not start a new path or subpath ctx.strokeText is not a function. (In 'ctx.strokeText('FAIL', 5, 35)', 'ctx.strokeText' is undefined) 6 PASS strokeText does not start a new path or subpath 7 7 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.draw.stroke.unaffected.worker-expected.txt
r262615 r270102 1 1 2 FAIL strokeText does not start a new path or subpath ctx.strokeText is not a function. (In 'ctx.strokeText('FAIL', 5, 35)', 'ctx.strokeText' is undefined) 2 PASS strokeText does not start a new path or subpath 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.font.default-expected.txt
r262615 r270102 2 2 3 3 4 FAIL OffscreenCanvas test: 2d.text.font.default assert_equals: ctx.font === '10px sans-serif' (got [undefined], expected 10px sans-serif[string]) expected (string) "10px sans-serif" but got (undefined) undefined 4 PASS OffscreenCanvas test: 2d.text.font.default 5 5 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.font.default.worker-expected.txt
r262615 r270102 1 1 2 FAIL 2d assert_equals: ctx.font === '10px sans-serif' (got [undefined], expected 10px sans-serif[string]) expected (string) "10px sans-serif" but got (undefined) undefined2 PASS 2d 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.font.parse.basic-expected.txt
r262615 r270102 2 2 3 3 4 FAIL OffscreenCanvas test: 2d.text.font.parse.basic assert_equals: ctx.font === '20px serif' (got 20PX SERIF[string], expected 20px serif[string]) expected "20px serif" but got "20PX SERIF" 4 PASS OffscreenCanvas test: 2d.text.font.parse.basic 5 5 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.font.parse.basic.worker-expected.txt
r262615 r270102 1 1 2 FAIL 2d assert_equals: ctx.font === '20px serif' (got 20PX SERIF[string], expected 20px serif[string]) expected "20px serif" but got "20PX SERIF"2 FAIL 2d assert_equals: ctx.font === '20px serif' (got 10px sans-serif[string], expected 20px serif[string]) expected "20px serif" but got "10px sans-serif" 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.font.parse.complex-expected.txt
r262615 r270102 2 2 3 3 4 FAIL OffscreenCanvas test: 2d.text.font.parse.complex assert_equals: ctx.font === 'italic small-caps 12px "Unknown Font", sans-serif' (got small-caps italic 400 12px/2 Unknown Font, sans-serif[string], expected italic small-caps 12px "Unknown Font", sans-serif[string]) expected "italic small-caps 12px \"Unknown Font\", sans-serif" but got "small-caps italic 400 12px/2 Unknown Font, sans-serif" 4 PASS OffscreenCanvas test: 2d.text.font.parse.complex 5 5 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.font.parse.complex.worker-expected.txt
r262615 r270102 1 1 2 FAIL 2d assert_equals: ctx.font === 'italic small-caps 12px "Unknown Font", sans-serif' (got small-caps italic 400 12px/2 Unknown Font, sans-serif[string], expected italic small-caps 12px "Unknown Font", sans-serif[string]) expected "italic small-caps 12px \"Unknown Font\", sans-serif" but got "small-caps italic 400 12px/2 Unknown Font,sans-serif"2 FAIL 2d assert_equals: ctx.font === 'italic small-caps 12px "Unknown Font", sans-serif' (got 10px sans-serif[string], expected italic small-caps 12px "Unknown Font", sans-serif[string]) expected "italic small-caps 12px \"Unknown Font\", sans-serif" but got "10px sans-serif" 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.font.parse.invalid-expected.txt
r262615 r270102 2 2 3 3 4 FAIL OffscreenCanvas test: 2d.text.font.parse.invalid assert_equals: ctx.font === '20px serif' (got bogus[string], expected 20px serif[string]) expected "20px serif" but got "bogus" 4 PASS OffscreenCanvas test: 2d.text.font.parse.invalid 5 5 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.font.parse.invalid.worker-expected.txt
r262615 r270102 1 1 2 FAIL 2d assert_equals: ctx.font === '20px serif' (got bogus[string], expected 20px serif[string]) expected "20px serif" but got "bogus"2 FAIL 2d assert_equals: ctx.font === '20px serif' (got 10px sans-serif[string], expected 20px serif[string]) expected "20px serif" but got "10px sans-serif" 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.font.parse.system-expected.txt
r262615 r270102 4 4 5 5 6 FAIL System fonts must be computed to explicit values assert_not_equals: ctx.font !== 'message-box' (got message-box[string], expected not message-box[string]) got disallowed value "message-box" 6 PASS System fonts must be computed to explicit values 7 7 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.font.parse.system.worker-expected.txt
r262615 r270102 1 1 2 FAIL System fonts must be computed to explicit values assert_not_equals: ctx.font !== 'message-box' (got message-box[string], expected not message-box[string]) got disallowed value "message-box" 2 PASS System fonts must be computed to explicit values 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.font.parse.tiny.worker-expected.txt
r267646 r270102 1 1 2 PASS 2d 2 FAIL 2d assert_equals: ctx.font === '1px sans-serif' (got 10px sans-serif[string], expected 1px sans-serif[string]) expected "1px sans-serif" but got "10px sans-serif" 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.measure.width.basic-expected.txt
r267646 r270102 1 1 2d.text.measure.width.basic 2 2 3 The width of character is same as font used for OffscreenCanvas 3 4 4 PASS OffscreenCanvas test: 2d.text.measure.width.basic5 5 6 PASS The width of character is same as font used for OffscreenCanvas 7 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.measure.width.basic.worker-expected.txt
r267646 r270102 1 1 2 PASS 2d 2 FAIL The width of character is same as font used for OffscreenCanvas Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.measure.width.empty-expected.txt
r267646 r270102 1 1 2d.text.measure.width.empty 2 2 3 The empty string has zero width 3 The empty string has zero width for OffscreenCanvas 4 4 5 5 6 PASS The empty string has zero width 6 PASS The empty string has zero width for OffscreenCanvas 7 7 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.measure.width.empty.worker-expected.txt
r267646 r270102 1 1 2 PASS The empty string has zero width 2 FAIL The empty string has zero width for OffscreenCanvas Can't find variable: FontFace 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.measure.width.space-expected.txt
r267646 r270102 1 1 2d.text.measure.width.space 2 2 3 Space characters are converted to U+0020 and collapsed (per CSS) 3 Space characters are converted to U+0020 and collapsed (per CSS) for OffscreenCanvas 4 4 5 5 6 PASS Space characters are converted to U+0020 and collapsed (per CSS) 6 FAIL Space characters are converted to U+0020 and collapsed (per CSS) for OffscreenCanvas assert_equals: ctx.measureText('A \x09\x0a\x0c\x0d \x09\x0a\x0c\x0dB').width === 150 (got 650[number], expected 150[number]) expected 150 but got 650 7 7 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/text/2d.text.measure.width.space.worker-expected.txt
r267646 r270102 1 1 2 PASS Space characters are converted to U+0020 and collapsed (per CSS) 2 FAIL Space characters are converted to U+0020 and collapsed (per CSS) for OffscreenCanvas Can't find variable: FontFace 3 3 -
trunk/LayoutTests/platform/glib/TestExpectations
r270017 r270102 527 527 #//////////////////////////////////////////////////////////////////////////////////////// 528 528 529 webkit.org/b/186759 imported/w3c/web-platform-tests/html/canvas/offscreen/text [ Skip ]530 529 webkit.org/b/203146 fast/canvas/offscreen-enabled.html [ Pass ] 531 530 webkit.org/b/203146 http/wpt/offscreen-canvas [ Pass ] -
trunk/Source/WebCore/ChangeLog
r270101 r270102 1 2020-11-20 Chris Lord <clord@igalia.com> 2 3 Enable font functions on OffscreenCanvas for main-thread 4 https://bugs.webkit.org/show_bug.cgi?id=219088 5 6 Reviewed by Simon Fraser. 7 8 Move some font-related code from CanvasRenderingContext2D to 9 CanvasRenderingContext2DBase so it can be shared by OffscreenCanvas 10 and enable font functions on the OffscreenCanvas rendering context. 11 Font setting only works when a Document is available, so this only 12 enables drawing/measuring of text on the main thread. 13 14 No new tests. Rebaselined existing tests. 15 16 * html/canvas/CanvasRenderingContext2D.cpp: 17 (WebCore::CanvasRenderingContext2D::measureText): 18 (WebCore::CanvasRenderingContext2D::fontProxy const): 19 (WebCore::CanvasRenderingContext2D::drawTextInternal): 20 * html/canvas/CanvasRenderingContext2D.h: 21 * html/canvas/CanvasRenderingContext2DBase.cpp: 22 (WebCore::CanvasRenderingContext2DBase::font const): 23 (WebCore::toCanvasTextAlign): 24 (WebCore::fromCanvasTextAlign): 25 (WebCore::CanvasRenderingContext2DBase::textAlign const): 26 (WebCore::CanvasRenderingContext2DBase::setTextAlign): 27 (WebCore::toCanvasTextBaseline): 28 (WebCore::fromCanvasTextBaseline): 29 (WebCore::CanvasRenderingContext2DBase::textBaseline const): 30 (WebCore::CanvasRenderingContext2DBase::setTextBaseline): 31 (WebCore::CanvasRenderingContext2DBase::setDirection): 32 (WebCore::CanvasRenderingContext2DBase::canDrawTextWithParams): 33 (WebCore::CanvasRenderingContext2DBase::normalizeSpaces): 34 (WebCore::CanvasRenderingContext2DBase::drawText): 35 (WebCore::CanvasRenderingContext2DBase::drawTextUnchecked): 36 (WebCore::CanvasRenderingContext2DBase::measureTextInternal): 37 (WebCore::CanvasRenderingContext2DBase::textOffset): 38 * html/canvas/CanvasRenderingContext2DBase.h: 39 (WebCore::CanvasRenderingContext2DBase::fontProxy): 40 * html/canvas/OffscreenCanvasRenderingContext2D.cpp: 41 (WebCore::OffscreenCanvasRenderingContext2D::setFont): 42 (WebCore::OffscreenCanvasRenderingContext2D::direction const): 43 (WebCore::OffscreenCanvasRenderingContext2D::fontProxy const): 44 (WebCore::OffscreenCanvasRenderingContext2D::fillText): 45 (WebCore::OffscreenCanvasRenderingContext2D::strokeText): 46 (WebCore::OffscreenCanvasRenderingContext2D::measureText): 47 * html/canvas/OffscreenCanvasRenderingContext2D.h: 48 * html/canvas/OffscreenCanvasRenderingContext2D.idl: 49 1 50 2020-11-20 Youenn Fablet <youenn@apple.com> 2 51 -
trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
r269957 r270102 99 99 } 100 100 101 String CanvasRenderingContext2D::font() const102 {103 if (!state().font.realized())104 return DefaultFont;105 106 StringBuilder serializedFont;107 const auto& fontDescription = state().font.fontDescription();108 109 if (fontDescription.italic())110 serializedFont.appendLiteral("italic ");111 if (fontDescription.variantCaps() == FontVariantCaps::Small)112 serializedFont.appendLiteral("small-caps ");113 114 serializedFont.appendNumber(fontDescription.computedPixelSize());115 serializedFont.appendLiteral("px");116 117 for (unsigned i = 0; i < fontDescription.familyCount(); ++i) {118 if (i)119 serializedFont.append(',');120 121 // FIXME: We should append family directly to serializedFont rather than building a temporary string.122 String family = fontDescription.familyAt(i);123 if (family.startsWith("-webkit-"))124 family = family.substring(8);125 if (family.contains(' '))126 family = makeString('"', family, '"');127 128 serializedFont.append(' ', family);129 }130 131 return serializedFont.toString();132 }133 134 101 void CanvasRenderingContext2D::setFont(const String& newFont) 135 102 { … … 167 134 if (auto fontStyle = Style::resolveForFontRaw(*fontRaw, WTFMove(fontDescription), document)) 168 135 modifiableState().font.initialize(document.fontSelector(), *fontStyle); 169 }170 171 static CanvasTextAlign toCanvasTextAlign(TextAlign textAlign)172 {173 switch (textAlign) {174 case StartTextAlign:175 return CanvasTextAlign::Start;176 case EndTextAlign:177 return CanvasTextAlign::End;178 case LeftTextAlign:179 return CanvasTextAlign::Left;180 case RightTextAlign:181 return CanvasTextAlign::Right;182 case CenterTextAlign:183 return CanvasTextAlign::Center;184 }185 186 ASSERT_NOT_REACHED();187 return CanvasTextAlign::Start;188 }189 190 static TextAlign fromCanvasTextAlign(CanvasTextAlign canvasTextAlign)191 {192 switch (canvasTextAlign) {193 case CanvasTextAlign::Start:194 return StartTextAlign;195 case CanvasTextAlign::End:196 return EndTextAlign;197 case CanvasTextAlign::Left:198 return LeftTextAlign;199 case CanvasTextAlign::Right:200 return RightTextAlign;201 case CanvasTextAlign::Center:202 return CenterTextAlign;203 }204 205 ASSERT_NOT_REACHED();206 return StartTextAlign;207 }208 209 CanvasTextAlign CanvasRenderingContext2D::textAlign() const210 {211 return toCanvasTextAlign(state().textAlign);212 }213 214 void CanvasRenderingContext2D::setTextAlign(CanvasTextAlign canvasTextAlign)215 {216 auto textAlign = fromCanvasTextAlign(canvasTextAlign);217 if (state().textAlign == textAlign)218 return;219 realizeSaves();220 modifiableState().textAlign = textAlign;221 }222 223 static CanvasTextBaseline toCanvasTextBaseline(TextBaseline textBaseline)224 {225 switch (textBaseline) {226 case TopTextBaseline:227 return CanvasTextBaseline::Top;228 case HangingTextBaseline:229 return CanvasTextBaseline::Hanging;230 case MiddleTextBaseline:231 return CanvasTextBaseline::Middle;232 case AlphabeticTextBaseline:233 return CanvasTextBaseline::Alphabetic;234 case IdeographicTextBaseline:235 return CanvasTextBaseline::Ideographic;236 case BottomTextBaseline:237 return CanvasTextBaseline::Bottom;238 }239 240 ASSERT_NOT_REACHED();241 return CanvasTextBaseline::Top;242 }243 244 static TextBaseline fromCanvasTextBaseline(CanvasTextBaseline canvasTextBaseline)245 {246 switch (canvasTextBaseline) {247 case CanvasTextBaseline::Top:248 return TopTextBaseline;249 case CanvasTextBaseline::Hanging:250 return HangingTextBaseline;251 case CanvasTextBaseline::Middle:252 return MiddleTextBaseline;253 case CanvasTextBaseline::Alphabetic:254 return AlphabeticTextBaseline;255 case CanvasTextBaseline::Ideographic:256 return IdeographicTextBaseline;257 case CanvasTextBaseline::Bottom:258 return BottomTextBaseline;259 }260 261 ASSERT_NOT_REACHED();262 return TopTextBaseline;263 }264 265 CanvasTextBaseline CanvasRenderingContext2D::textBaseline() const266 {267 return toCanvasTextBaseline(state().textBaseline);268 }269 270 void CanvasRenderingContext2D::setTextBaseline(CanvasTextBaseline canvasTextBaseline)271 {272 auto textBaseline = fromCanvasTextBaseline(canvasTextBaseline);273 if (state().textBaseline == textBaseline)274 return;275 realizeSaves();276 modifiableState().textBaseline = textBaseline;277 136 } 278 137 … … 301 160 } 302 161 303 void CanvasRenderingContext2D::setDirection(CanvasDirection direction)304 {305 if (state().direction == direction)306 return;307 308 realizeSaves();309 modifiableState().direction = direction;310 }311 312 162 void CanvasRenderingContext2D::fillText(const String& text, float x, float y, Optional<float> maxWidth) 313 163 { … … 331 181 } 332 182 333 static void normalizeSpaces(String& text)334 {335 size_t i = text.find(isSpaceThatNeedsReplacing);336 if (i == notFound)337 return;338 339 unsigned textLength = text.length();340 Vector<UChar> charVector(textLength);341 StringView(text).getCharactersWithUpconvert(charVector.data());342 343 charVector[i++] = ' ';344 345 for (; i < textLength; ++i) {346 if (isSpaceThatNeedsReplacing(charVector[i]))347 charVector[i] = ' ';348 }349 text = String::adopt(WTFMove(charVector));350 }351 352 183 Ref<TextMetrics> CanvasRenderingContext2D::measureText(const String& text) 353 184 { … … 357 188 ResourceLoadObserver::shared().logCanvasRead(canvas.document()); 358 189 } 359 190 360 191 Ref<TextMetrics> metrics = TextMetrics::create(); 361 192 … … 368 199 369 200 TextRun textRun(normalizedText, 0, 0, AllowRightExpansion, direction, override, true); 370 auto& font = fontProxy(); 371 auto& fontMetrics = font.fontMetrics(); 372 373 GlyphOverflow glyphOverflow; 374 glyphOverflow.computeBounds = true; 375 float fontWidth = font.width(textRun, &glyphOverflow); 376 metrics->setWidth(fontWidth); 377 378 FloatPoint offset = textOffset(fontWidth, direction); 379 380 metrics->setActualBoundingBoxAscent(glyphOverflow.top - offset.y()); 381 metrics->setActualBoundingBoxDescent(glyphOverflow.bottom + offset.y()); 382 metrics->setFontBoundingBoxAscent(fontMetrics.ascent() - offset.y()); 383 metrics->setFontBoundingBoxDescent(fontMetrics.descent() + offset.y()); 384 metrics->setEmHeightAscent(fontMetrics.ascent() - offset.y()); 385 metrics->setEmHeightDescent(fontMetrics.descent() + offset.y()); 386 metrics->setHangingBaseline(fontMetrics.ascent() - offset.y()); 387 metrics->setAlphabeticBaseline(-offset.y()); 388 metrics->setIdeographicBaseline(-fontMetrics.descent() - offset.y()); 389 390 metrics->setActualBoundingBoxLeft(glyphOverflow.left - offset.x()); 391 metrics->setActualBoundingBoxRight(fontWidth + glyphOverflow.right + offset.x()); 392 393 return metrics; 394 } 395 396 auto CanvasRenderingContext2D::fontProxy() -> const FontProxy& { 201 return measureTextInternal(textRun); 202 } 203 204 auto CanvasRenderingContext2D::fontProxy() -> const FontProxy* { 397 205 auto& canvas = downcast<HTMLCanvasElement>(canvasBase()); 398 206 canvas.document().updateStyleIfNeeded(); 399 207 if (!state().font.realized()) 400 208 setFont(state().unparsedFont); 401 return state().font; 402 } 403 404 FloatPoint CanvasRenderingContext2D::textOffset(float width, TextDirection direction) 405 { 406 auto& fontMetrics = fontProxy().fontMetrics(); 407 FloatPoint offset; 408 409 switch (state().textBaseline) { 410 case TopTextBaseline: 411 case HangingTextBaseline: 412 offset.setY(fontMetrics.ascent()); 413 break; 414 case BottomTextBaseline: 415 case IdeographicTextBaseline: 416 offset.setY(-fontMetrics.descent()); 417 break; 418 case MiddleTextBaseline: 419 offset.setY(fontMetrics.height() / 2 - fontMetrics.descent()); 420 break; 421 case AlphabeticTextBaseline: 422 default: 423 break; 424 } 425 426 bool isRTL = direction == TextDirection::RTL; 427 auto align = state().textAlign; 428 if (align == StartTextAlign) 429 align = isRTL ? RightTextAlign : LeftTextAlign; 430 else if (align == EndTextAlign) 431 align = isRTL ? LeftTextAlign : RightTextAlign; 432 433 switch (align) { 434 case CenterTextAlign: 435 offset.setX(-width / 2); 436 break; 437 case RightTextAlign: 438 offset.setX(-width); 439 break; 440 default: 441 break; 442 } 443 return offset; 209 return &state().font; 444 210 } 445 211 … … 448 214 if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled()) 449 215 ResourceLoadObserver::shared().logCanvasWriteOrMeasure(this->canvas().document(), text); 450 451 auto& fontProxy = this->fontProxy(); 452 const auto& fontMetrics = fontProxy.fontMetrics(); 453 454 auto* c = drawingContext(); 455 if (!c) 456 return; 457 if (!state().hasInvertibleTransform) 458 return; 459 if (!std::isfinite(x) | !std::isfinite(y)) 460 return; 461 if (maxWidth && (!std::isfinite(maxWidth.value()) || maxWidth.value() <= 0)) 462 return; 463 464 // If gradient size is zero, then paint nothing. 465 auto gradient = c->strokeGradient(); 466 if (!fill && gradient && gradient->isZeroSize()) 467 return; 468 469 gradient = c->fillGradient(); 470 if (fill && gradient && gradient->isZeroSize()) 216 217 if (!canDrawTextWithParams(x, y, fill, maxWidth)) 471 218 return; 472 219 473 220 String normalizedText = text; 474 221 normalizeSpaces(normalizedText); 475 476 // FIXME: Need to turn off font smoothing.477 222 478 223 const RenderStyle* computedStyle; … … 481 226 482 227 TextRun textRun(normalizedText, 0, 0, AllowRightExpansion, direction, override, true); 483 float fontWidth = fontProxy.width(textRun); 484 bool useMaxWidth = maxWidth && maxWidth.value() < fontWidth; 485 float width = useMaxWidth ? maxWidth.value() : fontWidth; 486 FloatPoint location(x, y); 487 location += textOffset(width, direction); 488 489 // The slop built in to this mask rect matches the heuristic used in FontCGWin.cpp for GDI text. 490 FloatRect textRect = FloatRect(location.x() - fontMetrics.height() / 2, location.y() - fontMetrics.ascent() - fontMetrics.lineGap(), 491 width + fontMetrics.height(), fontMetrics.lineSpacing()); 492 if (!fill) 493 inflateStrokeRect(textRect); 494 495 #if USE(CG) 496 const CanvasStyle& drawStyle = fill ? state().fillStyle : state().strokeStyle; 497 if (drawStyle.canvasGradient() || drawStyle.canvasPattern()) { 498 IntRect maskRect = enclosingIntRect(textRect); 499 500 // If we have a shadow, we need to draw it before the mask operation. 501 // Follow a procedure similar to paintTextWithShadows in TextPainter. 502 503 if (shouldDrawShadows()) { 504 GraphicsContextStateSaver stateSaver(*c); 505 506 FloatSize offset(0, 2 * maskRect.height()); 507 508 FloatSize shadowOffset; 509 float shadowRadius; 510 Color shadowColor; 511 c->getShadow(shadowOffset, shadowRadius, shadowColor); 512 513 FloatRect shadowRect(maskRect); 514 shadowRect.inflate(shadowRadius * 1.4); 515 shadowRect.move(shadowOffset * -1); 516 c->clip(shadowRect); 517 518 shadowOffset += offset; 519 520 c->setLegacyShadow(shadowOffset, shadowRadius, shadowColor); 521 522 if (fill) 523 c->setFillColor(Color::black); 524 else 525 c->setStrokeColor(Color::black); 526 527 fontProxy.drawBidiText(*c, textRun, location + offset, FontCascade::UseFallbackIfFontNotReady); 528 } 529 530 GraphicsContextStateSaver stateSaver(*c); 531 532 auto paintMaskImage = [&] (GraphicsContext& maskImageContext) { 533 if (fill) 534 maskImageContext.setFillColor(Color::black); 535 else { 536 maskImageContext.setStrokeColor(Color::black); 537 maskImageContext.setStrokeThickness(c->strokeThickness()); 538 } 539 540 maskImageContext.setTextDrawingMode(fill ? TextDrawingMode::Fill : TextDrawingMode::Stroke); 541 542 if (useMaxWidth) { 543 maskImageContext.translate(location - maskRect.location()); 544 // We draw when fontWidth is 0 so compositing operations (eg, a "copy" op) still work. 545 maskImageContext.scale(FloatSize((fontWidth > 0 ? (width / fontWidth) : 0), 1)); 546 fontProxy.drawBidiText(maskImageContext, textRun, FloatPoint(0, 0), FontCascade::UseFallbackIfFontNotReady); 547 } else { 548 maskImageContext.translate(-maskRect.location()); 549 fontProxy.drawBidiText(maskImageContext, textRun, location, FontCascade::UseFallbackIfFontNotReady); 550 } 551 }; 552 553 if (c->clipToDrawingCommands(maskRect, ColorSpace::SRGB, WTFMove(paintMaskImage)) == GraphicsContext::ClipToDrawingCommandsResult::FailedToCreateImageBuffer) 554 return; 555 556 drawStyle.applyFillColor(*c); 557 c->fillRect(maskRect); 558 return; 559 } 560 #endif 561 562 c->setTextDrawingMode(fill ? TextDrawingMode::Fill : TextDrawingMode::Stroke); 563 564 GraphicsContextStateSaver stateSaver(*c); 565 if (useMaxWidth) { 566 c->translate(location); 567 // We draw when fontWidth is 0 so compositing operations (eg, a "copy" op) still work. 568 c->scale(FloatSize((fontWidth > 0 ? (width / fontWidth) : 0), 1)); 569 location = FloatPoint(); 570 } 571 572 if (isFullCanvasCompositeMode(state().globalComposite)) { 573 beginCompositeLayer(); 574 fontProxy.drawBidiText(*c, textRun, location, FontCascade::UseFallbackIfFontNotReady); 575 endCompositeLayer(); 576 didDrawEntireCanvas(); 577 } else if (state().globalComposite == CompositeOperator::Copy) { 578 clearCanvas(); 579 fontProxy.drawBidiText(*c, textRun, location, FontCascade::UseFallbackIfFontNotReady); 580 didDrawEntireCanvas(); 581 } else { 582 fontProxy.drawBidiText(*c, textRun, location, FontCascade::UseFallbackIfFontNotReady); 583 didDraw(textRect); 584 } 228 drawTextUnchecked(textRun, x, y, fill, maxWidth); 585 229 } 586 230 -
trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.h
r246285 r270102 29 29 #include "CanvasTextAlign.h" 30 30 #include "CanvasTextBaseline.h" 31 #include "FontCascade.h"32 #include "FontSelectorClient.h"33 31 #include "HTMLCanvasElement.h" 34 32 #include <memory> … … 52 50 float webkitBackingStorePixelRatio() const { return 1; } 53 51 54 String font() const;55 52 void setFont(const String&); 56 53 57 CanvasTextAlign textAlign() const;58 void setTextAlign(CanvasTextAlign);59 60 CanvasTextBaseline textBaseline() const;61 void setTextBaseline(CanvasTextBaseline);62 63 54 CanvasDirection direction() const; 64 void setDirection(CanvasDirection);65 55 66 56 void fillText(const String& text, float x, float y, Optional<float> maxWidth = WTF::nullopt); … … 73 63 CanvasRenderingContext2D(CanvasBase&, bool usesCSSCompatibilityParseMode); 74 64 75 // The relationship between FontCascade and CanvasRenderingContext2D::FontProxy must hold certain invariants. 76 // Therefore, all font operations must pass through the State. 77 const FontProxy& fontProxy(); 65 const FontProxy* fontProxy() final; 78 66 79 67 void drawTextInternal(const String& text, float x, float y, bool fill, Optional<float> maxWidth = WTF::nullopt); … … 82 70 83 71 TextDirection toTextDirection(CanvasRenderingContext2DBase::Direction, const RenderStyle** computedStyle = nullptr) const; 84 85 FloatPoint textOffset(float width, TextDirection);86 72 }; 87 73 -
trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp
r269614 r270102 2253 2253 } 2254 2254 2255 String CanvasRenderingContext2DBase::font() const 2256 { 2257 if (!state().font.realized()) 2258 return DefaultFont; 2259 2260 StringBuilder serializedFont; 2261 const auto& fontDescription = state().font.fontDescription(); 2262 2263 if (fontDescription.italic()) 2264 serializedFont.appendLiteral("italic "); 2265 if (fontDescription.variantCaps() == FontVariantCaps::Small) 2266 serializedFont.appendLiteral("small-caps "); 2267 2268 serializedFont.appendNumber(fontDescription.computedPixelSize()); 2269 serializedFont.appendLiteral("px"); 2270 2271 for (unsigned i = 0; i < fontDescription.familyCount(); ++i) { 2272 if (i) 2273 serializedFont.append(','); 2274 2275 // FIXME: We should append family directly to serializedFont rather than building a temporary string. 2276 String family = fontDescription.familyAt(i); 2277 if (family.startsWith("-webkit-")) 2278 family = family.substring(8); 2279 if (family.contains(' ')) 2280 family = makeString('"', family, '"'); 2281 2282 serializedFont.append(' ', family); 2283 } 2284 2285 return serializedFont.toString(); 2286 } 2287 2288 static CanvasTextAlign toCanvasTextAlign(TextAlign textAlign) 2289 { 2290 switch (textAlign) { 2291 case StartTextAlign: 2292 return CanvasTextAlign::Start; 2293 case EndTextAlign: 2294 return CanvasTextAlign::End; 2295 case LeftTextAlign: 2296 return CanvasTextAlign::Left; 2297 case RightTextAlign: 2298 return CanvasTextAlign::Right; 2299 case CenterTextAlign: 2300 return CanvasTextAlign::Center; 2301 } 2302 2303 ASSERT_NOT_REACHED(); 2304 return CanvasTextAlign::Start; 2305 } 2306 2307 static TextAlign fromCanvasTextAlign(CanvasTextAlign canvasTextAlign) 2308 { 2309 switch (canvasTextAlign) { 2310 case CanvasTextAlign::Start: 2311 return StartTextAlign; 2312 case CanvasTextAlign::End: 2313 return EndTextAlign; 2314 case CanvasTextAlign::Left: 2315 return LeftTextAlign; 2316 case CanvasTextAlign::Right: 2317 return RightTextAlign; 2318 case CanvasTextAlign::Center: 2319 return CenterTextAlign; 2320 } 2321 2322 ASSERT_NOT_REACHED(); 2323 return StartTextAlign; 2324 } 2325 2326 CanvasTextAlign CanvasRenderingContext2DBase::textAlign() const 2327 { 2328 return toCanvasTextAlign(state().textAlign); 2329 } 2330 2331 void CanvasRenderingContext2DBase::setTextAlign(CanvasTextAlign canvasTextAlign) 2332 { 2333 auto textAlign = fromCanvasTextAlign(canvasTextAlign); 2334 if (state().textAlign == textAlign) 2335 return; 2336 realizeSaves(); 2337 modifiableState().textAlign = textAlign; 2338 } 2339 2340 static CanvasTextBaseline toCanvasTextBaseline(TextBaseline textBaseline) 2341 { 2342 switch (textBaseline) { 2343 case TopTextBaseline: 2344 return CanvasTextBaseline::Top; 2345 case HangingTextBaseline: 2346 return CanvasTextBaseline::Hanging; 2347 case MiddleTextBaseline: 2348 return CanvasTextBaseline::Middle; 2349 case AlphabeticTextBaseline: 2350 return CanvasTextBaseline::Alphabetic; 2351 case IdeographicTextBaseline: 2352 return CanvasTextBaseline::Ideographic; 2353 case BottomTextBaseline: 2354 return CanvasTextBaseline::Bottom; 2355 } 2356 2357 ASSERT_NOT_REACHED(); 2358 return CanvasTextBaseline::Top; 2359 } 2360 2361 static TextBaseline fromCanvasTextBaseline(CanvasTextBaseline canvasTextBaseline) 2362 { 2363 switch (canvasTextBaseline) { 2364 case CanvasTextBaseline::Top: 2365 return TopTextBaseline; 2366 case CanvasTextBaseline::Hanging: 2367 return HangingTextBaseline; 2368 case CanvasTextBaseline::Middle: 2369 return MiddleTextBaseline; 2370 case CanvasTextBaseline::Alphabetic: 2371 return AlphabeticTextBaseline; 2372 case CanvasTextBaseline::Ideographic: 2373 return IdeographicTextBaseline; 2374 case CanvasTextBaseline::Bottom: 2375 return BottomTextBaseline; 2376 } 2377 2378 ASSERT_NOT_REACHED(); 2379 return TopTextBaseline; 2380 } 2381 2382 CanvasTextBaseline CanvasRenderingContext2DBase::textBaseline() const 2383 { 2384 return toCanvasTextBaseline(state().textBaseline); 2385 } 2386 2387 void CanvasRenderingContext2DBase::setTextBaseline(CanvasTextBaseline canvasTextBaseline) 2388 { 2389 auto textBaseline = fromCanvasTextBaseline(canvasTextBaseline); 2390 if (state().textBaseline == textBaseline) 2391 return; 2392 realizeSaves(); 2393 modifiableState().textBaseline = textBaseline; 2394 } 2395 2396 void CanvasRenderingContext2DBase::setDirection(Direction direction) 2397 { 2398 if (state().direction == direction) 2399 return; 2400 2401 realizeSaves(); 2402 modifiableState().direction = direction; 2403 } 2404 2405 bool CanvasRenderingContext2DBase::canDrawTextWithParams(float x, float y, bool fill, Optional<float> maxWidth) 2406 { 2407 auto* c = drawingContext(); 2408 if (!c) 2409 return false; 2410 if (!this->fontProxy()->realized()) 2411 return false; 2412 if (!state().hasInvertibleTransform) 2413 return false; 2414 if (!std::isfinite(x) | !std::isfinite(y)) 2415 return false; 2416 if (maxWidth && (!std::isfinite(maxWidth.value()) || maxWidth.value() <= 0)) 2417 return false; 2418 2419 // If gradient size is zero, nothing would be painted. 2420 auto gradient = c->strokeGradient(); 2421 if (!fill && gradient && gradient->isZeroSize()) 2422 return false; 2423 2424 gradient = c->fillGradient(); 2425 if (fill && gradient && gradient->isZeroSize()) 2426 return false; 2427 2428 return true; 2429 } 2430 2431 void CanvasRenderingContext2DBase::normalizeSpaces(String& text) 2432 { 2433 size_t i = text.find(isSpaceThatNeedsReplacing); 2434 if (i == notFound) 2435 return; 2436 2437 unsigned textLength = text.length(); 2438 Vector<UChar> charVector(textLength); 2439 StringView(text).getCharactersWithUpconvert(charVector.data()); 2440 2441 charVector[i++] = ' '; 2442 2443 for (; i < textLength; ++i) { 2444 if (isSpaceThatNeedsReplacing(charVector[i])) 2445 charVector[i] = ' '; 2446 } 2447 text = String::adopt(WTFMove(charVector)); 2448 } 2449 2450 void CanvasRenderingContext2DBase::drawText(const String& text, float x, float y, bool fill, Optional<float> maxWidth) 2451 { 2452 if (!canDrawTextWithParams(x, y, fill, maxWidth)) 2453 return; 2454 2455 String normalizedText = text; 2456 normalizeSpaces(normalizedText); 2457 2458 auto direction = (state().direction == Direction::Rtl) ? TextDirection::RTL : TextDirection::LTR; 2459 TextRun textRun(normalizedText, 0, 0, AllowRightExpansion, direction, false, true); 2460 2461 drawTextUnchecked(textRun, x, y, fill, maxWidth); 2462 } 2463 2464 void CanvasRenderingContext2DBase::drawTextUnchecked(const TextRun& textRun, float x, float y, bool fill, Optional<float> maxWidth) 2465 { 2466 auto* c = drawingContext(); 2467 auto& fontProxy = *this->fontProxy(); 2468 const auto& fontMetrics = fontProxy.fontMetrics(); 2469 2470 // FIXME: Need to turn off font smoothing. 2471 2472 float fontWidth = fontProxy.width(textRun); 2473 bool useMaxWidth = maxWidth && maxWidth.value() < fontWidth; 2474 float width = useMaxWidth ? maxWidth.value() : fontWidth; 2475 FloatPoint location(x, y); 2476 location += textOffset(width, textRun.direction()); 2477 2478 // The slop built in to this mask rect matches the heuristic used in FontCGWin.cpp for GDI text. 2479 FloatRect textRect = FloatRect(location.x() - fontMetrics.height() / 2, location.y() - fontMetrics.ascent() - fontMetrics.lineGap(), 2480 width + fontMetrics.height(), fontMetrics.lineSpacing()); 2481 if (!fill) 2482 inflateStrokeRect(textRect); 2483 2484 #if USE(CG) 2485 const CanvasStyle& drawStyle = fill ? state().fillStyle : state().strokeStyle; 2486 if (drawStyle.canvasGradient() || drawStyle.canvasPattern()) { 2487 IntRect maskRect = enclosingIntRect(textRect); 2488 2489 // If we have a shadow, we need to draw it before the mask operation. 2490 // Follow a procedure similar to paintTextWithShadows in TextPainter. 2491 2492 if (shouldDrawShadows()) { 2493 GraphicsContextStateSaver stateSaver(*c); 2494 2495 FloatSize offset(0, 2 * maskRect.height()); 2496 2497 FloatSize shadowOffset; 2498 float shadowRadius; 2499 Color shadowColor; 2500 c->getShadow(shadowOffset, shadowRadius, shadowColor); 2501 2502 FloatRect shadowRect(maskRect); 2503 shadowRect.inflate(shadowRadius * 1.4); 2504 shadowRect.move(shadowOffset * -1); 2505 c->clip(shadowRect); 2506 2507 shadowOffset += offset; 2508 2509 c->setLegacyShadow(shadowOffset, shadowRadius, shadowColor); 2510 2511 if (fill) 2512 c->setFillColor(Color::black); 2513 else 2514 c->setStrokeColor(Color::black); 2515 2516 fontProxy.drawBidiText(*c, textRun, location + offset, FontCascade::UseFallbackIfFontNotReady); 2517 } 2518 2519 GraphicsContextStateSaver stateSaver(*c); 2520 2521 auto paintMaskImage = [&] (GraphicsContext& maskImageContext) { 2522 if (fill) 2523 maskImageContext.setFillColor(Color::black); 2524 else { 2525 maskImageContext.setStrokeColor(Color::black); 2526 maskImageContext.setStrokeThickness(c->strokeThickness()); 2527 } 2528 2529 maskImageContext.setTextDrawingMode(fill ? TextDrawingMode::Fill : TextDrawingMode::Stroke); 2530 2531 if (useMaxWidth) { 2532 maskImageContext.translate(location - maskRect.location()); 2533 // We draw when fontWidth is 0 so compositing operations (eg, a "copy" op) still work. 2534 maskImageContext.scale(FloatSize((fontWidth > 0 ? (width / fontWidth) : 0), 1)); 2535 fontProxy.drawBidiText(maskImageContext, textRun, FloatPoint(0, 0), FontCascade::UseFallbackIfFontNotReady); 2536 } else { 2537 maskImageContext.translate(-maskRect.location()); 2538 fontProxy.drawBidiText(maskImageContext, textRun, location, FontCascade::UseFallbackIfFontNotReady); 2539 } 2540 }; 2541 2542 if (c->clipToDrawingCommands(maskRect, ColorSpace::SRGB, WTFMove(paintMaskImage)) == GraphicsContext::ClipToDrawingCommandsResult::FailedToCreateImageBuffer) 2543 return; 2544 2545 drawStyle.applyFillColor(*c); 2546 c->fillRect(maskRect); 2547 return; 2548 } 2549 #endif 2550 2551 c->setTextDrawingMode(fill ? TextDrawingMode::Fill : TextDrawingMode::Stroke); 2552 2553 GraphicsContextStateSaver stateSaver(*c); 2554 if (useMaxWidth) { 2555 c->translate(location); 2556 // We draw when fontWidth is 0 so compositing operations (eg, a "copy" op) still work. 2557 c->scale(FloatSize((fontWidth > 0 ? (width / fontWidth) : 0), 1)); 2558 location = FloatPoint(); 2559 } 2560 2561 if (isFullCanvasCompositeMode(state().globalComposite)) { 2562 beginCompositeLayer(); 2563 fontProxy.drawBidiText(*c, textRun, location, FontCascade::UseFallbackIfFontNotReady); 2564 endCompositeLayer(); 2565 didDrawEntireCanvas(); 2566 } else if (state().globalComposite == CompositeOperator::Copy) { 2567 clearCanvas(); 2568 fontProxy.drawBidiText(*c, textRun, location, FontCascade::UseFallbackIfFontNotReady); 2569 didDrawEntireCanvas(); 2570 } else { 2571 fontProxy.drawBidiText(*c, textRun, location, FontCascade::UseFallbackIfFontNotReady); 2572 didDraw(textRect); 2573 } 2574 } 2575 2576 Ref<TextMetrics> CanvasRenderingContext2DBase::measureTextInternal(const String& text) 2577 { 2578 String normalizedText = text; 2579 normalizeSpaces(normalizedText); 2580 2581 auto direction = (state().direction == Direction::Rtl) ? TextDirection::RTL : TextDirection::LTR; 2582 TextRun textRun(normalizedText, 0, 0, AllowRightExpansion, direction, false, true); 2583 2584 return measureTextInternal(textRun); 2585 } 2586 2587 Ref<TextMetrics> CanvasRenderingContext2DBase::measureTextInternal(const TextRun& textRun) 2588 { 2589 Ref<TextMetrics> metrics = TextMetrics::create(); 2590 2591 auto& font = *fontProxy(); 2592 auto& fontMetrics = font.fontMetrics(); 2593 2594 GlyphOverflow glyphOverflow; 2595 glyphOverflow.computeBounds = true; 2596 float fontWidth = font.width(textRun, &glyphOverflow); 2597 metrics->setWidth(fontWidth); 2598 2599 FloatPoint offset = textOffset(fontWidth, textRun.direction()); 2600 2601 metrics->setActualBoundingBoxAscent(glyphOverflow.top - offset.y()); 2602 metrics->setActualBoundingBoxDescent(glyphOverflow.bottom + offset.y()); 2603 metrics->setFontBoundingBoxAscent(fontMetrics.ascent() - offset.y()); 2604 metrics->setFontBoundingBoxDescent(fontMetrics.descent() + offset.y()); 2605 metrics->setEmHeightAscent(fontMetrics.ascent() - offset.y()); 2606 metrics->setEmHeightDescent(fontMetrics.descent() + offset.y()); 2607 metrics->setHangingBaseline(fontMetrics.ascent() - offset.y()); 2608 metrics->setAlphabeticBaseline(-offset.y()); 2609 metrics->setIdeographicBaseline(-fontMetrics.descent() - offset.y()); 2610 2611 metrics->setActualBoundingBoxLeft(glyphOverflow.left - offset.x()); 2612 metrics->setActualBoundingBoxRight(fontWidth + glyphOverflow.right + offset.x()); 2613 2614 return metrics; 2615 } 2616 2617 FloatPoint CanvasRenderingContext2DBase::textOffset(float width, TextDirection direction) 2618 { 2619 auto& fontMetrics = fontProxy()->fontMetrics(); 2620 FloatPoint offset; 2621 2622 switch (state().textBaseline) { 2623 case TopTextBaseline: 2624 case HangingTextBaseline: 2625 offset.setY(fontMetrics.ascent()); 2626 break; 2627 case BottomTextBaseline: 2628 case IdeographicTextBaseline: 2629 offset.setY(-fontMetrics.descent()); 2630 break; 2631 case MiddleTextBaseline: 2632 offset.setY(fontMetrics.height() / 2 - fontMetrics.descent()); 2633 break; 2634 case AlphabeticTextBaseline: 2635 default: 2636 break; 2637 } 2638 2639 bool isRTL = direction == TextDirection::RTL; 2640 auto align = state().textAlign; 2641 if (align == StartTextAlign) 2642 align = isRTL ? RightTextAlign : LeftTextAlign; 2643 else if (align == EndTextAlign) 2644 align = isRTL ? LeftTextAlign : RightTextAlign; 2645 2646 switch (align) { 2647 case CenterTextAlign: 2648 offset.setX(-width / 2); 2649 break; 2650 case RightTextAlign: 2651 offset.setX(-width); 2652 break; 2653 default: 2654 break; 2655 } 2656 return offset; 2657 } 2658 2255 2659 } // namespace WebCore -
trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.h
r269331 r270102 220 220 void setUsesDisplayListDrawing(bool flag) { m_usesDisplayListDrawing = flag; }; 221 221 222 String font() const; 223 224 CanvasTextAlign textAlign() const; 225 void setTextAlign(CanvasTextAlign); 226 227 CanvasTextBaseline textBaseline() const; 228 void setTextBaseline(CanvasTextBaseline); 229 222 230 using Direction = CanvasDirection; 231 void setDirection(Direction); 223 232 224 233 class FontProxy : public FontSelectorClient { … … 372 381 bool hasInvertibleTransform() const override { return state().hasInvertibleTransform; } 373 382 383 // The relationship between FontCascade and CanvasRenderingContext2D::FontProxy must hold certain invariants. 384 // Therefore, all font operations must pass through the proxy. 385 virtual const FontProxy* fontProxy() { return nullptr; } 386 387 static void normalizeSpaces(String&); 388 bool canDrawTextWithParams(float x, float y, bool fill, Optional<float> maxWidth = WTF::nullopt); 389 void drawText(const String& text, float x, float y, bool fill, Optional<float> maxWidth = WTF::nullopt); 390 void drawTextUnchecked(const TextRun&, float x, float y, bool fill, Optional<float> maxWidth = WTF::nullopt); 391 Ref<TextMetrics> measureTextInternal(const String& text); 392 Ref<TextMetrics> measureTextInternal(const TextRun&); 393 394 FloatPoint textOffset(float width, TextDirection); 395 374 396 static const unsigned MaxSaveCount = 1024 * 16; 375 397 Vector<State, 1> m_stateStack; -
trunk/Source/WebCore/html/canvas/OffscreenCanvasRenderingContext2D.cpp
r265543 r270102 36 36 #if ENABLE(OFFSCREEN_CANVAS) 37 37 38 #include "CSSFontSelector.h" 39 #include "CSSParser.h" 40 #include "CSSPropertyParserHelpers.h" 41 #include "Document.h" 42 #include "RenderStyle.h" 43 #include "StyleResolveForFontRaw.h" 44 #include "TextMetrics.h" 38 45 #include <wtf/IsoMallocInlines.h> 39 46 … … 54 61 } 55 62 63 void OffscreenCanvasRenderingContext2D::setFont(const String& newFont) 64 { 65 auto& context = *canvasBase().scriptExecutionContext(); 66 if (!is<Document>(context)) 67 return; 68 69 if (newFont.isEmpty()) 70 return; 71 72 if (newFont == state().unparsedFont && state().font.realized()) 73 return; 74 75 // According to http://lists.w3.org/Archives/Public/public-html/2009Jul/0947.html, 76 // the "inherit" and "initial" values must be ignored. parseFontWorkerSafe() ignores these. 77 auto fontRaw = CSSParser::parseFontWorkerSafe(newFont, strictToCSSParserMode(!m_usesCSSCompatibilityParseMode)); 78 if (!fontRaw) 79 return; 80 81 // The parse succeeded. 82 String newFontSafeCopy(newFont); // Create a string copy since newFont can be deleted inside realizeSaves. 83 realizeSaves(); 84 modifiableState().unparsedFont = newFontSafeCopy; 85 86 // Map the <canvas> font into the text style. If the font uses keywords like larger/smaller, these will work 87 // relative to the default font. 88 FontCascadeDescription fontDescription; 89 fontDescription.setOneFamily(DefaultFontFamily); 90 fontDescription.setSpecifiedSize(DefaultFontSize); 91 fontDescription.setComputedSize(DefaultFontSize); 92 93 auto& document = downcast<Document>(context); 94 auto fontStyle = Style::resolveForFontRaw(*fontRaw, WTFMove(fontDescription), document); 95 96 if (fontStyle) 97 modifiableState().font.initialize(document.fontSelector(), *fontStyle); 98 } 99 100 CanvasDirection OffscreenCanvasRenderingContext2D::direction() const 101 { 102 // FIXME: What should we do about inherit here? 103 switch (state().direction) { 104 case Direction::Inherit: 105 case Direction::Ltr: 106 return Direction::Ltr; 107 case Direction::Rtl: 108 return Direction::Rtl; 109 } 110 ASSERT_NOT_REACHED(); 111 return Direction::Ltr; 112 } 113 114 auto OffscreenCanvasRenderingContext2D::fontProxy() -> const FontProxy* { 115 if (!state().font.realized()) 116 setFont(state().unparsedFont); 117 return &state().font; 118 } 119 120 void OffscreenCanvasRenderingContext2D::fillText(const String& text, float x, float y, Optional<float> maxWidth) 121 { 122 drawText(text, x, y, true, maxWidth); 123 } 124 125 void OffscreenCanvasRenderingContext2D::strokeText(const String& text, float x, float y, Optional<float> maxWidth) 126 { 127 drawText(text, x, y, false, maxWidth); 128 } 129 130 Ref<TextMetrics> OffscreenCanvasRenderingContext2D::measureText(const String& text) 131 { 132 return measureTextInternal(text); 133 } 134 56 135 } // namespace WebCore 57 136 -
trunk/Source/WebCore/html/canvas/OffscreenCanvasRenderingContext2D.h
r265543 r270102 45 45 46 46 void commit(); 47 48 void setFont(const String&); 49 CanvasDirection direction() const; 50 void fillText(const String& text, float x, float y, Optional<float> maxWidth = WTF::nullopt); 51 void strokeText(const String& text, float x, float y, Optional<float> maxWidth = WTF::nullopt); 52 Ref<TextMetrics> measureText(const String& text); 53 54 private: 55 const FontProxy* fontProxy() final; 47 56 }; 48 57 -
trunk/Source/WebCore/html/canvas/OffscreenCanvasRenderingContext2D.idl
r266523 r270102 51 51 OffscreenCanvasRenderingContext2D includes CanvasRect; 52 52 OffscreenCanvasRenderingContext2D includes CanvasDrawPath; 53 OffscreenCanvasRenderingContext2D includes CanvasText; 53 54 OffscreenCanvasRenderingContext2D includes CanvasDrawImage; 54 55 OffscreenCanvasRenderingContext2D includes CanvasImageData; 55 56 OffscreenCanvasRenderingContext2D includes CanvasPathDrawingStyles; 57 OffscreenCanvasRenderingContext2D includes CanvasTextDrawingStyles; 56 58 OffscreenCanvasRenderingContext2D includes CanvasPath;
Note: See TracChangeset
for help on using the changeset viewer.