Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support text rotation #22

Merged
merged 1 commit into from
Jan 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/scatter-panning/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/wgpu-winit/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"width": 257,
"width": 272,
"height": 102,
"origin_x": 51,
"origin_x": 66,
"origin_y": 5
}
Binary file modified sg2d-vega-test-data/vega-scenegraphs/text/bar_axis_labels.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions sg2d-vega-test-data/vega-scenegraphs/text/bar_axis_labels.sg.json
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"width": 210,
"height": 210,
"origin_x": 5,
"origin_y": 5
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
112 changes: 112 additions & 0 deletions sg2d-vega-test-data/vega-scenegraphs/text/text_rotation.sg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
{
"marktype": "group",
"name": "root",
"role": "frame",
"interactive": true,
"clip": false,
"items": [
{
"items": [
{
"marktype": "symbol",
"name": "points",
"role": "mark",
"interactive": true,
"clip": false,
"items": [
{
"x": 40,
"y": 15,
"fill": "orange",
"size": 30,
"shape": "triangle-up",
"angle": 0
},
{
"x": 20,
"y": 70,
"fill": "blue",
"size": 30,
"shape": "triangle-up",
"angle": 30
},
{
"x": 80,
"y": 160,
"fill": "green",
"size": 30,
"shape": "triangle-up",
"angle": -90
},
{
"x": 120,
"y": 160,
"fill": "purple",
"size": 30,
"shape": "triangle-up",
"angle": -27
}
],
"zindex": 0
},
{
"marktype": "text",
"name": "text",
"role": "mark",
"interactive": true,
"clip": false,
"items": [
{
"x": 40,
"y": 15,
"baseline": "top",
"fill": "orange",
"text": "hello",
"angle": 0,
"font": "Helvetica",
"fontSize": 20
},
{
"x": 20,
"y": 70,
"baseline": "middle",
"fill": "blue",
"text": "hello",
"angle": 30,
"font": "Helvetica",
"fontSize": 20
},
{
"x": 80,
"y": 160,
"baseline": "bottom",
"fill": "green",
"text": "hello",
"angle": -90,
"font": "Helvetica",
"fontSize": 20
},
{
"x": 120,
"y": 160,
"baseline": "alphabetic",
"fill": "purple",
"text": "hello",
"angle": -27,
"font": "Helvetica",
"fontSize": 20
}
],
"zindex": 0
}
],
"x": 0,
"y": 0,
"width": 200,
"height": 200,
"fill": "transparent",
"stroke": "transparent"
}
],
"zindex": 0
}
5 changes: 3 additions & 2 deletions sg2d-vega-test-data/vega-specs/text/bar_axis_labels.vg.json
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,10 @@
"scale": "y",
"orient": "left",
"grid": false,
"title": "Activity",
"zindex": 0,
"labelFont": "Helvetica",
"titleFont": "Helvetica",
"zindex": 0
"titleFont": "Helvetica"
}
]
}
53 changes: 53 additions & 0 deletions sg2d-vega-test-data/vega-specs/text/text_rotation.vg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "A scatterplot showing horsepower and miles per gallons for various cars.",
"background": "white",
"padding": 5,
"width": 200,
"height": 200,
"style": "cell",
"config": {"style": {"cell": {"stroke": "transparent"}}},
"data": [{
"name": "source_0",
"values": [
{"x": 40, "y": 15, "fill": "orange", "angle": 0, "baseline": "top"},
{"x": 20, "y": 70, "fill": "blue", "angle": 30, "baseline": "middle"},
{"x": 80, "y": 160, "fill": "green", "angle": -90, "baseline": "bottom"},
{"x": 120, "y": 160, "fill": "purple", "angle": -27, "baseline": "alphabetic"}
]
}],
"marks": [
{
"name": "points",
"type": "symbol",
"from": {"data": "source_0"},
"encode": {
"update": {
"shape": {"value": "triangle-up"},
"size": {"value": 30},
"fill": {"field": "fill"},
"x": {"field": "x" },
"y": {"field": "y"},
"angle": {"field": "angle"}
}
}
},
{
"name": "text",
"type": "text",
"from": {"data": "source_0"},
"encode": {
"update": {
"text": {"value": "hello"},
"font": {"value": "Helvetica"},
"fontSize": {"value": 20},
"fill": {"field": "fill"},
"x": {"field": "x" },
"y": {"field": "y"},
"angle": {"field": "angle"},
"baseline": {"field": "baseline"}
}
}
}
]
}
4 changes: 3 additions & 1 deletion sg2d-wgpu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ cgmath = "0.18.0"
itertools = "0.12.0"
image = "0.24.7"
futures-intrusive = "^0.5"
glyphon = { git = "https://github.com/grovesNL/glyphon.git", rev="941309aed230d7110bfec0d4af502ecb4648cf90" }

# glyphon branch that includes text rotation support: https://github.com/jonmmease/glyphon/pull/1
glyphon = { git = "https://github.com/jonmmease/glyphon.git", rev="c468f5dacd4130b27a29b098c4de3f4d5c146209" }
lyon = { workspace = true }

[dev-dependencies]
Expand Down
30 changes: 20 additions & 10 deletions sg2d-wgpu/src/marks/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ impl TextMarkRenderer {
.iter()
.zip(&self.instances)
.map(|(buffer, instance)| {
let (width, height) = measure(buffer);
let (width, line_y, height) = measure(buffer);
let scaled_x = instance.position[0] * self.uniform.scale;
let scaled_y = instance.position[1] * self.uniform.scale;
let left = match instance.align {
Expand All @@ -197,8 +197,7 @@ impl TextMarkRenderer {
};

let mut top = match instance.baseline {
TextBaselineSpec::Alphabetic => 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,
Expand All @@ -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::<Vec<_>>();
Expand Down Expand Up @@ -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),
)
}
3 changes: 2 additions & 1 deletion sg2d-wgpu/tests/test_image_baselines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(
Expand Down