commit 020b811b98c7e5bde90a00f417fefd2c5d3b9b0c
parent a64cd98732976e29500ccd076d697865c6a93810
Author: Lee Salzman <lsalzman@mozilla.com>
Date: Sat, 8 Nov 2025 21:51:21 +0000
Bug 1998946 - Handle capped degenerate lines in AAStroke. r=aosmond
Differential Revision: https://phabricator.services.mozilla.com/D271893
Diffstat:
6 files changed, 42 insertions(+), 12 deletions(-)
diff --git a/.cargo/config.toml.in b/.cargo/config.toml.in
@@ -5,9 +5,9 @@
[source.crates-io]
replace-with = "vendored-sources"
-[source."git+https://github.com/FirefoxGraphics/aa-stroke?rev=a821fa621c2def48e90c82774b4c6563b5a8ea4a"]
+[source."git+https://github.com/FirefoxGraphics/aa-stroke?rev=5776bdfc8ad664a1503db668fab397d818a5f98a"]
git = "https://github.com/FirefoxGraphics/aa-stroke"
-rev = "a821fa621c2def48e90c82774b4c6563b5a8ea4a"
+rev = "5776bdfc8ad664a1503db668fab397d818a5f98a"
replace-with = "vendored-sources"
[source."git+https://github.com/FirefoxGraphics/wpf-gpu-raster?rev=99979da091fd58fba8477e7fcdf5ec0727102916"]
diff --git a/Cargo.lock b/Cargo.lock
@@ -5,7 +5,7 @@ version = 3
[[package]]
name = "aa-stroke"
version = "0.1.0"
-source = "git+https://github.com/FirefoxGraphics/aa-stroke?rev=a821fa621c2def48e90c82774b4c6563b5a8ea4a#a821fa621c2def48e90c82774b4c6563b5a8ea4a"
+source = "git+https://github.com/FirefoxGraphics/aa-stroke?rev=5776bdfc8ad664a1503db668fab397d818a5f98a#5776bdfc8ad664a1503db668fab397d818a5f98a"
dependencies = [
"euclid",
]
diff --git a/third_party/rust/aa-stroke/.cargo-checksum.json b/third_party/rust/aa-stroke/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{".github/workflows/rust.yml":"6a9f1b122ea02367a2f1ff1fc7b9a728284ceb47fad12e1610cde9d760f4efc3","Cargo.toml":"5eb59a34fcee8bd5c03b43f199f6ebcb0039b0c4570fd7f0e62dcde1f809043b","README.md":"60b34cfa653114d5054009696df2ed2ea1d4926a6bc312d0cac4b84845c2beff","examples/simple.rs":"3d4da451711d20ed8d593abaad0fe47bf840aa5a42fd8f52d8b0896362001089","src/bezierflattener.rs":"6afe01b228b5e05878550af16beee71f0ef7f881203e5fa24d1b628c360908e6","src/c_bindings.rs":"06225ddd132ae959eda1b445f4e375cead4d8e135c5cba81e828815fe6a5e88b","src/lib.rs":"3daf47db60245b72d8c2649e14cdaccd3d46acd83a83234122c06f9e156acead","src/tri_rasterize.rs":"a01a730551b4b6be78cbc10fe404c9c7f0c2fc46884accfb212f3232d3dc47b7"},"package":null}
-\ No newline at end of file
+{"files":{".github/workflows/rust.yml":"6a9f1b122ea02367a2f1ff1fc7b9a728284ceb47fad12e1610cde9d760f4efc3","Cargo.toml":"5eb59a34fcee8bd5c03b43f199f6ebcb0039b0c4570fd7f0e62dcde1f809043b","README.md":"7adc73acac598188897754f41e37844d2a95dae913df4bfa4e83156afae953d3","examples/simple.rs":"3d4da451711d20ed8d593abaad0fe47bf840aa5a42fd8f52d8b0896362001089","src/bezierflattener.rs":"6afe01b228b5e05878550af16beee71f0ef7f881203e5fa24d1b628c360908e6","src/c_bindings.rs":"06225ddd132ae959eda1b445f4e375cead4d8e135c5cba81e828815fe6a5e88b","src/lib.rs":"dc37a9cb0aa23aaf6b691ad204d406aa0f5b71d16be4d1ebb4715a26b939cd0a","src/tri_rasterize.rs":"a01a730551b4b6be78cbc10fe404c9c7f0c2fc46884accfb212f3232d3dc47b7"},"package":null}
+\ No newline at end of file
diff --git a/third_party/rust/aa-stroke/README.md b/third_party/rust/aa-stroke/README.md
@@ -8,5 +8,5 @@ before passing them to the stroker. Other transforms are not currently (or ever?
### TODO
- using triangle strips instead of triangle lists
-- handle curves more efficiently than just flattening to lines
- handle cusps of curves more correctly
+- dashing
diff --git a/third_party/rust/aa-stroke/src/lib.rs b/third_party/rust/aa-stroke/src/lib.rs
@@ -733,9 +733,21 @@ impl<'z> Stroker<'z> {
// if we have a butt cap end the line half a pixel early so we have room to put the cap.
// XXX: this will probably mess things up if the line is shorter than 1/2 pixel long
self.line_to(if self.stroked_path.aa && self.style.cap == LineCap::Butt { pt + perp(normal) * 0.5} else { pt });
- if let (Some(cur_pt), Some((_point, _normal))) = (self.cur_pt, self.start_point) {
- // cap end
- cap_line(&mut self.stroked_path, &self.style, cur_pt, self.last_normal);
+ if let Some(cur_pt) = self.cur_pt {
+ if let Some((_point, _normal)) = self.start_point {
+ // cap end
+ cap_line(&mut self.stroked_path, &self.style, cur_pt, self.last_normal);
+ } else {
+ // If the line degenerates to a point and has a cap style that extends beyond
+ // the point, then draw both the start and end caps.
+ match self.style.cap {
+ LineCap::Round | LineCap::Square => {
+ cap_line(&mut self.stroked_path, &self.style, cur_pt, Vector::new(1., 0.));
+ cap_line(&mut self.stroked_path, &self.style, cur_pt, Vector::new(-1., 0.));
+ }
+ LineCap::Butt => {}
+ }
+ }
}
}
self.start_point = None;
@@ -1279,4 +1291,23 @@ fn joins_between_curves() {
let result = rasterize_to_mask(&vertices, 1, 1);
assert_eq!(result[0], 255);
-}
-\ No newline at end of file
+}
+
+#[test]
+fn round_cap_points() {
+ // Ensure degenerate lines with round caps are drawn.
+ let mut stroker = Stroker::new(&StrokeStyle{
+ cap: LineCap::Round,
+ join: LineJoin::Miter,
+ width: 11.5,
+ ..Default::default()});
+ stroker.move_to(Point::new(23., 34.5), false);
+ stroker.line_to_capped(Point::new(23., 34.5));
+ stroker.move_to(Point::new(92.0625, 46.), false);
+ stroker.line_to_capped(Point::new(92.0625, 46.));
+ stroker.move_to(Point::new(23., 57.5), false);
+ stroker.line_to_capped(Point::new(23., 57.5));
+ stroker.move_to(Point::new(92.0625, 57.5), false);
+ stroker.line_to_capped(Point::new(92.0625, 57.5));
+ assert_eq!(stroker.finish().len(), 576);
+}
diff --git a/toolkit/library/rust/shared/Cargo.toml b/toolkit/library/rust/shared/Cargo.toml
@@ -106,7 +106,7 @@ processtools = { path = "../../../components/processtools" }
qcms = { path = "../../../../gfx/qcms", features = ["c_bindings", "neon"], default-features = false }
wpf-gpu-raster = { git = "https://github.com/FirefoxGraphics/wpf-gpu-raster", rev = "99979da091fd58fba8477e7fcdf5ec0727102916" }
-aa-stroke = { git = "https://github.com/FirefoxGraphics/aa-stroke", rev = "a821fa621c2def48e90c82774b4c6563b5a8ea4a" }
+aa-stroke = { git = "https://github.com/FirefoxGraphics/aa-stroke", rev = "5776bdfc8ad664a1503db668fab397d818a5f98a" }
etagere = { version = "0.2.13", features = ["ffi"] }
url = "2.5.7"