From 8d781c391c823fdd64479ef819f75be45221d23d Mon Sep 17 00:00:00 2001 From: Jon Mease Date: Sat, 13 Jan 2024 12:30:27 -0500 Subject: [PATCH] Support test rotation --- Cargo.lock | 2 +- examples/scatter-panning/Cargo.lock | 2 +- examples/wgpu-winit/Cargo.lock | 2 +- .../text/bar_axis_labels.dims.json | 4 +- .../vega-scenegraphs/text/bar_axis_labels.png | Bin 33212 -> 35779 bytes .../text/bar_axis_labels.sg.json | 22 ++++ .../text/text_rotation.dims.json | 6 + .../vega-scenegraphs/text/text_rotation.png | Bin 0 -> 18383 bytes .../text/text_rotation.sg.json | 112 ++++++++++++++++++ .../vega-specs/text/bar_axis_labels.vg.json | 5 +- .../vega-specs/text/text_rotation.vg.json | 53 +++++++++ sg2d-wgpu/Cargo.toml | 4 +- sg2d-wgpu/src/marks/text.rs | 30 +++-- sg2d-wgpu/tests/test_image_baselines.rs | 3 +- 14 files changed, 226 insertions(+), 19 deletions(-) create mode 100644 sg2d-vega-test-data/vega-scenegraphs/text/text_rotation.dims.json create mode 100644 sg2d-vega-test-data/vega-scenegraphs/text/text_rotation.png create mode 100644 sg2d-vega-test-data/vega-scenegraphs/text/text_rotation.sg.json create mode 100644 sg2d-vega-test-data/vega-specs/text/text_rotation.vg.json diff --git a/Cargo.lock b/Cargo.lock index 6b5db51..de9a81d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2446,7 +2446,7 @@ dependencies = [ [[package]] name = "glyphon" version = "0.3.0" -source = "git+https://github.com/grovesNL/glyphon.git?rev=941309aed230d7110bfec0d4af502ecb4648cf90#941309aed230d7110bfec0d4af502ecb4648cf90" +source = "git+https://github.com/jonmmease/glyphon.git?rev=c468f5dacd4130b27a29b098c4de3f4d5c146209#c468f5dacd4130b27a29b098c4de3f4d5c146209" dependencies = [ "cosmic-text", "etagere", diff --git a/examples/scatter-panning/Cargo.lock b/examples/scatter-panning/Cargo.lock index f9cd148..907a04f 100644 --- a/examples/scatter-panning/Cargo.lock +++ b/examples/scatter-panning/Cargo.lock @@ -724,7 +724,7 @@ dependencies = [ [[package]] name = "glyphon" version = "0.3.0" -source = "git+https://github.com/grovesNL/glyphon.git?rev=941309aed230d7110bfec0d4af502ecb4648cf90#941309aed230d7110bfec0d4af502ecb4648cf90" +source = "git+https://github.com/jonmmease/glyphon.git?rev=0fb93c93da055337590dbf90cf8575374bcdb9ce#0fb93c93da055337590dbf90cf8575374bcdb9ce" dependencies = [ "cosmic-text", "etagere", diff --git a/examples/wgpu-winit/Cargo.lock b/examples/wgpu-winit/Cargo.lock index d68edba..c32a8d3 100644 --- a/examples/wgpu-winit/Cargo.lock +++ b/examples/wgpu-winit/Cargo.lock @@ -724,7 +724,7 @@ dependencies = [ [[package]] name = "glyphon" version = "0.3.0" -source = "git+https://github.com/grovesNL/glyphon.git?rev=941309aed230d7110bfec0d4af502ecb4648cf90#941309aed230d7110bfec0d4af502ecb4648cf90" +source = "git+https://github.com/jonmmease/glyphon.git?rev=0fb93c93da055337590dbf90cf8575374bcdb9ce#0fb93c93da055337590dbf90cf8575374bcdb9ce" dependencies = [ "cosmic-text", "etagere", diff --git a/sg2d-vega-test-data/vega-scenegraphs/text/bar_axis_labels.dims.json b/sg2d-vega-test-data/vega-scenegraphs/text/bar_axis_labels.dims.json index 25e83d0..119931d 100644 --- a/sg2d-vega-test-data/vega-scenegraphs/text/bar_axis_labels.dims.json +++ b/sg2d-vega-test-data/vega-scenegraphs/text/bar_axis_labels.dims.json @@ -1,6 +1,6 @@ { - "width": 257, + "width": 272, "height": 102, - "origin_x": 51, + "origin_x": 66, "origin_y": 5 } \ No newline at end of file diff --git a/sg2d-vega-test-data/vega-scenegraphs/text/bar_axis_labels.png b/sg2d-vega-test-data/vega-scenegraphs/text/bar_axis_labels.png index ce00df12d8c8d4d5c7d193fed7926855ec4e6a23..f2832df13c06fd1f4aebfb56637cd1535c7df8b0 100644 GIT binary patch literal 35779 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 literal 33212 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 diff --git a/sg2d-vega-test-data/vega-scenegraphs/text/bar_axis_labels.sg.json b/sg2d-vega-test-data/vega-scenegraphs/text/bar_axis_labels.sg.json index 9556005..d9235b6 100644 --- a/sg2d-vega-test-data/vega-scenegraphs/text/bar_axis_labels.sg.json +++ b/sg2d-vega-test-data/vega-scenegraphs/text/bar_axis_labels.sg.json @@ -485,6 +485,28 @@ } ], "zindex": 0 + }, + { + "marktype": "text", + "role": "axis-title", + "interactive": false, + "clip": false, + "items": [ + { + "x": -49.9208984375, + "y": 30, + "align": "center", + "baseline": "bottom", + "fill": "#000", + "opacity": 1, + "text": "Activity", + "angle": -90, + "font": "Helvetica", + "fontSize": 11, + "fontWeight": "bold" + } + ], + "zindex": 0 } ], "x": 0.5, diff --git a/sg2d-vega-test-data/vega-scenegraphs/text/text_rotation.dims.json b/sg2d-vega-test-data/vega-scenegraphs/text/text_rotation.dims.json new file mode 100644 index 0000000..0977cec --- /dev/null +++ b/sg2d-vega-test-data/vega-scenegraphs/text/text_rotation.dims.json @@ -0,0 +1,6 @@ +{ + "width": 210, + "height": 210, + "origin_x": 5, + "origin_y": 5 +} \ No newline at end of file diff --git a/sg2d-vega-test-data/vega-scenegraphs/text/text_rotation.png b/sg2d-vega-test-data/vega-scenegraphs/text/text_rotation.png new file mode 100644 index 0000000000000000000000000000000000000000..c4e64e08af34f192e94042661519c965287e115d GIT binary patch literal 18383 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 scaled_y - height, - + TextBaselineSpec::Alphabetic => scaled_y - line_y, TextBaselineSpec::Top => scaled_y, TextBaselineSpec::Middle => scaled_y - height * 0.5, TextBaselineSpec::Bottom => scaled_y - height, @@ -225,6 +224,8 @@ impl TextMarkRenderer { (instance.color[1] * 255.0) as u8, (instance.color[2] * 255.0) as u8, ), + angle: instance.angle, + rotation_origin: Some([scaled_x, scaled_y]), } }) .collect::>(); @@ -270,11 +271,20 @@ impl TextMarkRenderer { } } -pub fn measure(buffer: &Buffer) -> (f32, f32) { - let (width, total_lines) = buffer - .layout_runs() - .fold((0.0, 0usize), |(width, total_lines), run| { - (run.line_w.max(width), total_lines + 1) - }); - (width, (total_lines as f32 * buffer.metrics().line_height)) +pub fn measure(buffer: &Buffer) -> (f32, f32, f32) { + let (width, line_y, total_lines) = + buffer + .layout_runs() + .fold((0.0, 0.0, 0usize), |(width, line_y, total_lines), run| { + ( + run.line_w.max(width), + run.line_y.max(line_y), + total_lines + 1, + ) + }); + ( + width, + line_y, + (total_lines as f32 * buffer.metrics().line_height), + ) } diff --git a/sg2d-wgpu/tests/test_image_baselines.rs b/sg2d-wgpu/tests/test_image_baselines.rs index b85dec8..459d308 100644 --- a/sg2d-wgpu/tests/test_image_baselines.rs +++ b/sg2d-wgpu/tests/test_image_baselines.rs @@ -42,7 +42,8 @@ mod test_image_baselines { case("rule", "wide_rule_axes", 0.0001), case("rule", "wide_transparent_caps", 0.0001), case("rule", "dashed_rules", 0.0001), - case("text", "bar_axis_labels", 0.01) + case("text", "bar_axis_labels", 0.01), + case("text", "text_rotation", 0.015) )] fn test_image_baseline(category: &str, spec_name: &str, tolerance: f64) { let specs_dir = format!(