Backed out 3 changesets (bug 1656236) for wrench failures on filter-drop-shadow-clip-3.yaml. CLOSED TREE
Backed out changeset 78205b816ac8 (bug 1656236) Backed out changeset dc4ccb5a8ea9 (bug 1656236) Backed out changeset dcfa644ba078 (bug 1656236)
8
Cargo.lock
generated
@ -1331,9 +1331,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "euclid"
|
||||
version = "0.22.0"
|
||||
version = "0.20.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ab0e07e345fb061928646949fdf5fb888e5d75a57385e7f5856e45be289e745"
|
||||
checksum = "2bb7ef65b3777a325d1eeefefab5b6d4959da54747e33bd6258e789640f307ad"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"serde",
|
||||
@ -3736,9 +3736,9 @@ checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
|
||||
|
||||
[[package]]
|
||||
name = "plane-split"
|
||||
version = "0.17.0"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2211e7ccc9b6260779dd9bad59f7b10889d6361974623b9e405afd7e7e764654"
|
||||
checksum = "ffe16a646a08f4b4dd74035b9ff8e378eb1a4012a74f14f5889e7001cdbece33"
|
||||
dependencies = [
|
||||
"binary-space-partition",
|
||||
"euclid",
|
||||
|
@ -12,7 +12,7 @@ dirs = "2"
|
||||
rayon = "1"
|
||||
num_cpus = "1.7.0"
|
||||
tracy-rs = "0.1"
|
||||
euclid = { version = "0.22.0", features = ["serde"] }
|
||||
euclid = { version = "0.20.14", features = ["serde"] }
|
||||
app_units = "0.7"
|
||||
gleam = "0.12.0"
|
||||
log = "0.4"
|
||||
|
@ -134,7 +134,7 @@ impl SwTile {
|
||||
} else {
|
||||
self.valid_rect.translate(origin.to_vector())
|
||||
};
|
||||
let device_rect = transform.outer_transformed_rect(&bounds.to_f32().cast_unit()).unwrap().round_out().to_i32();
|
||||
let device_rect = transform.transform_rect(&bounds.to_f32().cast_unit()).unwrap().round_out().to_i32();
|
||||
device_rect.cast_unit().intersection(clip_rect)
|
||||
}
|
||||
|
||||
@ -161,7 +161,7 @@ impl SwTile {
|
||||
clip_rect: &DeviceIntRect,
|
||||
) -> Option<(DeviceIntRect, DeviceIntRect, bool)> {
|
||||
let valid = self.valid_rect.translate(self.origin(surface).to_vector());
|
||||
let valid = transform.outer_transformed_rect(&valid.to_f32().cast_unit()).unwrap().round_out().to_i32();
|
||||
let valid = transform.transform_rect(&valid.to_f32().cast_unit()).unwrap().round_out().to_i32();
|
||||
valid.cast_unit().intersection(clip_rect).map(|r| (r.translate(-valid.origin.to_vector().cast_unit()), r, transform.m22 < 0.0))
|
||||
}
|
||||
}
|
||||
|
28
gfx/wr/Cargo.lock
generated
@ -469,7 +469,7 @@ dependencies = [
|
||||
name = "direct-composition"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"euclid 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gleam 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mozangle 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender 0.61.0",
|
||||
@ -522,7 +522,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "euclid"
|
||||
version = "0.22.0"
|
||||
version = "0.20.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1151,7 +1151,7 @@ dependencies = [
|
||||
name = "peek-poke"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"euclid 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"peek-poke-derive 0.2.1",
|
||||
]
|
||||
|
||||
@ -1178,11 +1178,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "plane-split"
|
||||
version = "0.17.0"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -1627,7 +1627,7 @@ dependencies = [
|
||||
name = "tileview"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"euclid 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender 0.61.0",
|
||||
@ -1805,7 +1805,7 @@ dependencies = [
|
||||
"core-text 19.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cstr 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dwrote 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"freetype 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gleam 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1817,7 +1817,7 @@ dependencies = [
|
||||
"malloc_size_of_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mozangle 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"plane-split 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"plane-split 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"png 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1842,7 +1842,7 @@ dependencies = [
|
||||
"app_units 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gleam 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glutin 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1861,7 +1861,7 @@ dependencies = [
|
||||
"core-graphics 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-channel 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"derive_more 0.99.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"malloc_size_of_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"peek-poke 0.2.0",
|
||||
"serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1954,7 +1954,7 @@ name = "wr_malloc_size_of"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"app_units 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1972,7 +1972,7 @@ dependencies = [
|
||||
"crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dwrote 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"font-loader 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gleam 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glutin 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2113,7 +2113,7 @@ dependencies = [
|
||||
"checksum dwrote 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "439a1c2ba5611ad3ed731280541d36d2e9c4ac5e7fb818a27b604bdc5a6aa65b"
|
||||
"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
|
||||
"checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38"
|
||||
"checksum euclid 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7ab0e07e345fb061928646949fdf5fb888e5d75a57385e7f5856e45be289e745"
|
||||
"checksum euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c6a5b0c779cd0b744c73a1d2083faf181080d696903cdad99a3b03d015d7030"
|
||||
"checksum expat-sys 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "658f19728920138342f68408b7cf7644d90d4784353d8ebc32e7e8663dbe45fa"
|
||||
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||
"checksum font-loader 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c49d6b4c11dca1a1dd931a34a9f397e2da91abe3de4110505f3530a80e560b52"
|
||||
@ -2188,7 +2188,7 @@ dependencies = [
|
||||
"checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b"
|
||||
"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||
"checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
|
||||
"checksum plane-split 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2211e7ccc9b6260779dd9bad59f7b10889d6361974623b9e405afd7e7e764654"
|
||||
"checksum plane-split 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffe16a646a08f4b4dd74035b9ff8e378eb1a4012a74f14f5889e7001cdbece33"
|
||||
"checksum png 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)" = "910f09135b1ed14bb16be445a8c23ddf0777eca485fbfc7cee00d81fecab158a"
|
||||
"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
|
||||
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||
|
@ -6,7 +6,7 @@ license = "MPL-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
euclid = "0.22"
|
||||
euclid = "0.20"
|
||||
gleam = "0.12"
|
||||
mozangle = {version = "0.3.1", features = ["egl"]}
|
||||
webrender = {path = "../webrender"}
|
||||
|
@ -56,7 +56,7 @@ debug = ["webrender/capture", "webrender/debugger", "webrender/profiler"]
|
||||
[dependencies]
|
||||
app_units = "0.7"
|
||||
env_logger = "0.5"
|
||||
euclid = "0.22"
|
||||
euclid = "0.20"
|
||||
gleam = "0.12"
|
||||
glutin = "0.21"
|
||||
rayon = "1"
|
||||
|
@ -165,9 +165,9 @@ impl Example for App {
|
||||
self.angle0 += delta_angle * 0.1;
|
||||
self.angle1 += delta_angle * 0.2;
|
||||
self.angle2 -= delta_angle * 0.15;
|
||||
let xf0 = LayoutTransform::rotation(0.0, 0.0, 1.0, Angle::radians(self.angle0));
|
||||
let xf1 = LayoutTransform::rotation(0.0, 0.0, 1.0, Angle::radians(self.angle1));
|
||||
let xf2 = LayoutTransform::rotation(0.0, 0.0, 1.0, Angle::radians(self.angle2));
|
||||
let xf0 = LayoutTransform::create_rotation(0.0, 0.0, 1.0, Angle::radians(self.angle0));
|
||||
let xf1 = LayoutTransform::create_rotation(0.0, 0.0, 1.0, Angle::radians(self.angle1));
|
||||
let xf2 = LayoutTransform::create_rotation(0.0, 0.0, 1.0, Angle::radians(self.angle2));
|
||||
let mut txn = Transaction::new();
|
||||
txn.update_dynamic_properties(
|
||||
DynamicProperties {
|
||||
|
@ -8,7 +8,7 @@ license = "MIT/Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
euclid = { version = "0.22.0", optional = true }
|
||||
euclid = { version = "0.20.0", optional = true }
|
||||
peek-poke-derive = { version = "0.2", path = "./peek-poke-derive", optional = true }
|
||||
|
||||
[features]
|
||||
|
@ -12,4 +12,4 @@ ron = "0.5"
|
||||
serde = {version = "1.0.88", features = ["derive"] }
|
||||
webrender = {path = "../webrender", features=["capture","replay","debugger","png","profiler","no_static_freetype", "leak_checks"]}
|
||||
webrender_api = {path = "../webrender_api", features=["serialize","deserialize"]}
|
||||
euclid = { version = "0.22.0", features = ["serde"] }
|
||||
euclid = { version = "0.20.0", features = ["serde"] }
|
||||
|
@ -73,7 +73,7 @@ fn tile_node_to_svg(node: &TileNode,
|
||||
{
|
||||
match &node.kind {
|
||||
TileNodeKind::Leaf { .. } => {
|
||||
let rect_world = transform.outer_transformed_rect(&node.rect.to_rect()).unwrap();
|
||||
let rect_world = transform.transform_rect(&node.rect.to_rect()).unwrap();
|
||||
format!("<rect x=\"{:.2}\" y=\"{:.2}\" width=\"{:.2}\" height=\"{:.2}\" />\n",
|
||||
rect_world.origin.x * svg_settings.scale + svg_settings.x,
|
||||
rect_world.origin.y * svg_settings.scale + svg_settings.y,
|
||||
@ -296,7 +296,7 @@ fn tile_to_svg(key: TileOffset,
|
||||
origin: tile.rect.origin,
|
||||
size: PictureSize::new(1.0, 1.0)
|
||||
};
|
||||
let rect_visual_id_world = slice.transform.outer_transformed_rect(&rect_visual_id).unwrap();
|
||||
let rect_visual_id_world = slice.transform.transform_rect(&rect_visual_id).unwrap();
|
||||
svg += &format!("\n<text class=\"svg_tile_visual_id\" x=\"{}\" y=\"{}\">{},{} ({})</text>",
|
||||
rect_visual_id_world.origin.x * svg_settings.scale + svg_settings.x,
|
||||
(rect_visual_id_world.origin.y + 110.0) * svg_settings.scale + svg_settings.y,
|
||||
@ -312,7 +312,7 @@ fn tile_to_svg(key: TileOffset,
|
||||
origin: PicturePoint::new(rect.min.x, rect.min.y),
|
||||
size: PictureSize::new(rect.max.x - rect.min.x, rect.max.y - rect.min.y),
|
||||
};
|
||||
let rect_world = slice.transform.outer_transformed_rect(&rect_pixel).unwrap();
|
||||
let rect_world = slice.transform.transform_rect(&rect_pixel).unwrap();
|
||||
|
||||
let style =
|
||||
if let Some(prev_tile) = prev_tile {
|
||||
|
@ -32,7 +32,7 @@ bitflags = "1.2"
|
||||
byteorder = "1.0"
|
||||
cfg-if = "0.1.2"
|
||||
cstr = "0.1.2"
|
||||
euclid = { version = "0.22.0", features = ["serde"] }
|
||||
euclid = { version = "0.20.0", features = ["serde"] }
|
||||
fxhash = "0.2.1"
|
||||
gleam = "0.12.1"
|
||||
image_loader = { optional = true, version = "0.23", package = "image", default-features = false, features = ["png"] }
|
||||
@ -40,7 +40,7 @@ lazy_static = "1"
|
||||
log = "0.4"
|
||||
malloc_size_of_derive = "0.1"
|
||||
num-traits = "0.2"
|
||||
plane-split = "0.17"
|
||||
plane-split = "0.15"
|
||||
png = { optional = true, version = "0.16" }
|
||||
rayon = "1"
|
||||
ron = { optional = true, version = "0.5" }
|
||||
|
@ -1191,7 +1191,7 @@ impl BatchBuilder {
|
||||
root_spatial_node_index,
|
||||
).into_transform()
|
||||
.with_destination::<WorldPixel>()
|
||||
.then(&euclid::Transform3D::from_scale(ctx.global_device_pixel_scale));
|
||||
.post_transform(&euclid::Transform3D::from_scale(ctx.global_device_pixel_scale));
|
||||
|
||||
let glyph_translation = DeviceVector2D::new(glyph_transform.m41, glyph_transform.m42);
|
||||
|
||||
@ -1250,7 +1250,9 @@ impl BatchBuilder {
|
||||
let intersected = match pic_bounding_rect {
|
||||
// The text run may have been clipped, for example if part of it is offscreen.
|
||||
// So intersect our result with the original bounding rect.
|
||||
Some(rect) => rect.intersection(bounding_rect).unwrap_or_else(PictureRect::zero),
|
||||
Some(rect) => rect
|
||||
.intersection(bounding_rect)
|
||||
.unwrap_or_else(PictureRect::zero),
|
||||
// If space mapping went off the rails, fall back to the old behavior.
|
||||
//TODO: consider skipping the glyph run completely in this case.
|
||||
None => *bounding_rect,
|
||||
@ -2483,14 +2485,14 @@ impl BatchBuilder {
|
||||
let specific_resource_address = cache_item.uv_rect_handle.as_int(gpu_cache);
|
||||
prim_header.specific_prim_address = gpu_cache.get_address(&ctx.globals.default_image_handle);
|
||||
|
||||
let segment_local_clip_rect = match prim_header.local_clip_rect.intersection(&segment.local_rect) {
|
||||
Some(rect) => rect,
|
||||
None => { continue; }
|
||||
};
|
||||
let segment_local_clip_rect = prim_header.local_clip_rect.intersection(&segment.local_rect);
|
||||
if segment_local_clip_rect.is_none() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let segment_prim_header = PrimitiveHeader {
|
||||
local_rect: segment.local_rect,
|
||||
local_clip_rect: segment_local_clip_rect,
|
||||
local_clip_rect: segment_local_clip_rect.unwrap(),
|
||||
specific_prim_address: prim_header.specific_prim_address,
|
||||
transform_id: prim_header.transform_id,
|
||||
};
|
||||
|
@ -1067,12 +1067,12 @@ fn add_corner_segment(
|
||||
return;
|
||||
}
|
||||
|
||||
let segment_rect = match image_rect.intersection(&non_overlapping_rect) {
|
||||
Some(rect) => rect,
|
||||
None => {
|
||||
return;
|
||||
}
|
||||
};
|
||||
let segment_rect = image_rect.intersection(&non_overlapping_rect)
|
||||
.unwrap_or_else(LayoutRect::zero);
|
||||
|
||||
if segment_rect.size.width <= 0. || segment_rect.size.height <= 0. {
|
||||
return;
|
||||
}
|
||||
|
||||
let texture_rect = segment_rect
|
||||
.translate(-image_rect.origin.to_vector())
|
||||
|
@ -3,7 +3,8 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use api::{ColorF, YuvColorSpace, YuvFormat, ImageRendering, ExternalImageId};
|
||||
use api::units::*;
|
||||
use api::units::{DeviceRect, DeviceIntSize, DeviceIntRect, DeviceIntPoint, WorldRect};
|
||||
use api::units::{DevicePixelScale, DevicePoint, PictureRect, TexelRect, DevicePixel};
|
||||
use crate::batch::{resolve_image, get_buffer_kind};
|
||||
use euclid::Transform3D;
|
||||
use crate::gpu_cache::GpuCache;
|
||||
@ -572,7 +573,7 @@ impl CompositeState {
|
||||
surface_id: tile_cache.native_surface.as_ref().map(|s| s.opaque),
|
||||
offset: tile_cache.device_position,
|
||||
clip_rect: device_clip_rect,
|
||||
transform: CompositorSurfaceTransform::translation(tile_cache.device_position.x,
|
||||
transform: CompositorSurfaceTransform::create_translation(tile_cache.device_position.x,
|
||||
tile_cache.device_position.y,
|
||||
0.0),
|
||||
image_dependencies: [ImageDependency::INVALID; 3],
|
||||
@ -748,7 +749,7 @@ impl CompositeState {
|
||||
surface_id: tile_cache.native_surface.as_ref().map(|s| s.alpha),
|
||||
offset: tile_cache.device_position,
|
||||
clip_rect: device_clip_rect,
|
||||
transform: CompositorSurfaceTransform::translation(tile_cache.device_position.x,
|
||||
transform: CompositorSurfaceTransform::create_translation(tile_cache.device_position.x,
|
||||
tile_cache.device_position.y,
|
||||
0.0),
|
||||
image_dependencies: [ImageDependency::INVALID; 3],
|
||||
|
@ -2781,7 +2781,7 @@ impl Device {
|
||||
debug_assert!(self.shader_is_ready);
|
||||
|
||||
self.gl
|
||||
.uniform_matrix_4fv(program.u_transform, false, &transform.to_array());
|
||||
.uniform_matrix_4fv(program.u_transform, false, &transform.to_row_major_array());
|
||||
}
|
||||
|
||||
pub fn switch_mode(&self, mode: i32) {
|
||||
|
@ -245,7 +245,7 @@ impl<Src, Dst> From<CoordinateSpaceMapping<Src, Dst>> for TransformKey {
|
||||
CoordinateSpaceMapping::Transform(ref m) => {
|
||||
TransformKey::Transform {
|
||||
m: MatrixKey {
|
||||
m: m.to_array(),
|
||||
m: m.to_row_major_array(),
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -974,7 +974,7 @@ impl Tile {
|
||||
/// Print debug information about this tile to a tree printer.
|
||||
fn print(&self, pt: &mut dyn PrintTreePrinter) {
|
||||
pt.new_level(format!("Tile {:?}", self.id));
|
||||
pt.add_item(format!("local_tile_rect: {:?}", self.local_tile_rect));
|
||||
pt.add_item(format!("local_tile_rect: {}", self.local_tile_rect));
|
||||
pt.add_item(format!("fract_offset: {:?}", self.fract_offset));
|
||||
pt.add_item(format!("background_color: {:?}", self.background_color));
|
||||
pt.add_item(format!("invalidation_reason: {:?}", self.invalidation_reason));
|
||||
@ -3076,7 +3076,7 @@ impl TileCacheInstance {
|
||||
);
|
||||
let prim_origin = Vector3D::new(local_prim_rect.origin.x, local_prim_rect.origin.y, 0.0);
|
||||
let world_to_device_scale = Transform3D::from_scale(frame_context.global_device_pixel_scale);
|
||||
let transform = surface_to_world_mapper.get_transform().pre_translate(prim_origin).then(&world_to_device_scale);
|
||||
let transform = surface_to_world_mapper.get_transform().pre_translate(prim_origin).post_transform(&world_to_device_scale);
|
||||
|
||||
(local_prim_rect.cast_unit(), transform)
|
||||
}
|
||||
@ -3245,7 +3245,7 @@ impl TileCacheInstance {
|
||||
};
|
||||
|
||||
// If the rect is invalid, no need to create dependencies.
|
||||
if prim_rect.size.is_empty() {
|
||||
if prim_rect.size.is_empty_or_negative() {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
@ -1798,7 +1798,7 @@ fn get_clipped_device_rect(
|
||||
) -> Option<DeviceRect> {
|
||||
let unclipped_raster_rect = {
|
||||
let world_rect = *unclipped * Scale::new(1.0);
|
||||
let raster_rect = world_rect * device_pixel_scale.inverse();
|
||||
let raster_rect = world_rect * device_pixel_scale.inv();
|
||||
|
||||
raster_rect.cast_unit()
|
||||
};
|
||||
|
@ -520,7 +520,7 @@ impl Document {
|
||||
}
|
||||
|
||||
fn has_pixels(&self) -> bool {
|
||||
!self.view.scene.device_rect.size.is_empty()
|
||||
!self.view.scene.device_rect.size.is_empty_or_negative()
|
||||
}
|
||||
|
||||
fn process_frame_msg(
|
||||
|
@ -258,7 +258,7 @@ impl<T: RenderTarget> RenderTargetList<T> {
|
||||
}
|
||||
};
|
||||
|
||||
if alloc_size.is_empty() && self.targets.is_empty() {
|
||||
if alloc_size.is_empty_or_negative() && self.targets.is_empty() {
|
||||
// push an unused target here, only if we don't have any
|
||||
self.targets.push(T::new(self.screen_size, self.gpu_supports_fast_clears));
|
||||
}
|
||||
|
@ -573,7 +573,7 @@ pub fn dump_render_tasks_as_svg(
|
||||
|
||||
let saved = if task.saved_index.is_some() { " (Saved)" } else { "" };
|
||||
let label = text(tx, ty, format!("{}{}", task.kind.as_str(), saved));
|
||||
let size = text(tx, ty + 12.0, format!("{:?}", task.location.size()));
|
||||
let size = text(tx, ty + 12.0, format!("{}", task.location.size()));
|
||||
|
||||
nodes[task_index] = Some(Node { rect, label, size });
|
||||
|
||||
|
@ -486,7 +486,7 @@ impl<'a> SceneBuilder<'a> {
|
||||
match rotation {
|
||||
Rotation::Degree0 |
|
||||
Rotation::Degree180 => {
|
||||
LayoutTransform::scale(
|
||||
LayoutTransform::create_scale(
|
||||
content_size.width / scale_from.width,
|
||||
content_size.height / scale_from.height,
|
||||
1.0
|
||||
@ -494,7 +494,7 @@ impl<'a> SceneBuilder<'a> {
|
||||
},
|
||||
Rotation::Degree90 |
|
||||
Rotation::Degree270 => {
|
||||
LayoutTransform::scale(
|
||||
LayoutTransform::create_scale(
|
||||
content_size.height / scale_from.width,
|
||||
content_size.width / scale_from.height,
|
||||
1.0
|
||||
@ -509,12 +509,12 @@ impl<'a> SceneBuilder<'a> {
|
||||
if vertical_flip {
|
||||
let content_size = &self.iframe_size.last().unwrap();
|
||||
transform = transform
|
||||
.then_translate(LayoutVector3D::new(0.0, content_size.height, 0.0))
|
||||
.post_translate(LayoutVector3D::new(0.0, content_size.height, 0.0))
|
||||
.pre_scale(1.0, -1.0, 1.0);
|
||||
}
|
||||
|
||||
let rotate = rotation.to_matrix(**content_size);
|
||||
let transform = transform.then(&rotate);
|
||||
let transform = transform.post_transform(&rotate);
|
||||
|
||||
PropertyBinding::Value(transform)
|
||||
},
|
||||
|
@ -410,7 +410,7 @@ impl SpatialNode {
|
||||
// perspective matrix using the scroll offset.
|
||||
source_transform
|
||||
.pre_translate(scroll_offset)
|
||||
.then_translate(-scroll_offset)
|
||||
.post_translate(-scroll_offset)
|
||||
}
|
||||
ReferenceFrameKind::Perspective { scrolling_relative_to: None } |
|
||||
ReferenceFrameKind::Transform | ReferenceFrameKind::Zoom => source_transform,
|
||||
@ -425,7 +425,7 @@ impl SpatialNode {
|
||||
// between our reference frame and this node. Finally, we also include
|
||||
// whatever local transformation this reference frame provides.
|
||||
let relative_transform = resolved_transform
|
||||
.then_translate(snap_offset(state.parent_accumulated_scroll_offset, state.coordinate_system_relative_scale_offset.scale, global_device_pixel_scale))
|
||||
.post_translate(snap_offset(state.parent_accumulated_scroll_offset, state.coordinate_system_relative_scale_offset.scale, global_device_pixel_scale))
|
||||
.to_transform()
|
||||
.with_destination::<LayoutPixel>();
|
||||
|
||||
@ -462,9 +462,9 @@ impl SpatialNode {
|
||||
if reset_cs_id {
|
||||
// If we break 2D axis alignment or have a perspective component, we need to start a
|
||||
// new incompatible coordinate system with which we cannot share clips without masking.
|
||||
let transform = relative_transform.then(
|
||||
&state.coordinate_system_relative_scale_offset.to_transform()
|
||||
);
|
||||
let transform = state.coordinate_system_relative_scale_offset
|
||||
.to_transform()
|
||||
.pre_transform(&relative_transform);
|
||||
|
||||
// Push that new coordinate system and record the new id.
|
||||
let coord_system = {
|
||||
@ -473,7 +473,7 @@ impl SpatialNode {
|
||||
if parent_system.should_flatten {
|
||||
cur_transform.flatten_z_output();
|
||||
}
|
||||
let world_transform = cur_transform.then(&parent_system.world_transform);
|
||||
let world_transform = cur_transform.post_transform(&parent_system.world_transform);
|
||||
let determinant = world_transform.determinant();
|
||||
info.invertible = determinant != 0.0 && !determinant.is_nan();
|
||||
|
||||
@ -977,7 +977,7 @@ fn test_cst_perspective_relative_scroll() {
|
||||
let mut cst = SpatialTree::new();
|
||||
let pipeline_id = PipelineId::dummy();
|
||||
let ext_scroll_id = ExternalScrollId(1, pipeline_id);
|
||||
let transform = LayoutTransform::perspective(100.0);
|
||||
let transform = LayoutTransform::create_perspective(100.0);
|
||||
|
||||
let root = cst.add_reference_frame(
|
||||
None,
|
||||
|
@ -289,16 +289,16 @@ impl SpatialTree {
|
||||
let child_cs = &self.coord_systems[child.coordinate_system_id.0 as usize];
|
||||
let child_transform = child.content_transform
|
||||
.to_transform::<LayoutPixel, LayoutPixel>()
|
||||
.then(&child_cs.world_transform);
|
||||
.post_transform(&child_cs.world_transform);
|
||||
let parent_cs = &self.coord_systems[parent.coordinate_system_id.0 as usize];
|
||||
let parent_transform = parent.content_transform
|
||||
.to_transform()
|
||||
.then(&parent_cs.world_transform);
|
||||
.post_transform(&parent_cs.world_transform);
|
||||
|
||||
let result = parent_transform
|
||||
.inverse()
|
||||
.unwrap_or_default()
|
||||
.then(&child_transform)
|
||||
.post_transform(&child_transform)
|
||||
.with_source::<LayoutPixel>()
|
||||
.with_destination::<LayoutPixel>();
|
||||
return CoordinateSpaceMapping::Transform(result);
|
||||
@ -319,10 +319,10 @@ impl SpatialTree {
|
||||
}
|
||||
|
||||
coordinate_system_id = coord_system.parent.expect("invalid parent!");
|
||||
transform = transform.then(&coord_system.transform);
|
||||
transform = transform.post_transform(&coord_system.transform);
|
||||
}
|
||||
|
||||
transform = transform.then(
|
||||
transform = transform.post_transform(
|
||||
&parent.content_transform
|
||||
.inverse()
|
||||
.to_transform(),
|
||||
@ -352,7 +352,7 @@ impl SpatialTree {
|
||||
};
|
||||
let transform = scale_offset
|
||||
.to_transform()
|
||||
.then(&system.world_transform);
|
||||
.post_transform(&system.world_transform);
|
||||
|
||||
CoordinateSpaceMapping::Transform(transform)
|
||||
}
|
||||
@ -827,21 +827,21 @@ fn test_cst_simple_translation() {
|
||||
let child1 = add_reference_frame(
|
||||
&mut cst,
|
||||
Some(root),
|
||||
LayoutTransform::translation(100.0, 0.0, 0.0),
|
||||
LayoutTransform::create_translation(100.0, 0.0, 0.0),
|
||||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
let child2 = add_reference_frame(
|
||||
&mut cst,
|
||||
Some(child1),
|
||||
LayoutTransform::translation(0.0, 50.0, 0.0),
|
||||
LayoutTransform::create_translation(0.0, 50.0, 0.0),
|
||||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
let child3 = add_reference_frame(
|
||||
&mut cst,
|
||||
Some(child2),
|
||||
LayoutTransform::translation(200.0, 200.0, 0.0),
|
||||
LayoutTransform::create_translation(200.0, 200.0, 0.0),
|
||||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
@ -869,21 +869,21 @@ fn test_cst_simple_scale() {
|
||||
let child1 = add_reference_frame(
|
||||
&mut cst,
|
||||
Some(root),
|
||||
LayoutTransform::scale(4.0, 1.0, 1.0),
|
||||
LayoutTransform::create_scale(4.0, 1.0, 1.0),
|
||||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
let child2 = add_reference_frame(
|
||||
&mut cst,
|
||||
Some(child1),
|
||||
LayoutTransform::scale(1.0, 2.0, 1.0),
|
||||
LayoutTransform::create_scale(1.0, 2.0, 1.0),
|
||||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
let child3 = add_reference_frame(
|
||||
&mut cst,
|
||||
Some(child2),
|
||||
LayoutTransform::scale(2.0, 2.0, 1.0),
|
||||
LayoutTransform::create_scale(2.0, 2.0, 1.0),
|
||||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
@ -912,28 +912,28 @@ fn test_cst_scale_translation() {
|
||||
let child1 = add_reference_frame(
|
||||
&mut cst,
|
||||
Some(root),
|
||||
LayoutTransform::translation(100.0, 50.0, 0.0),
|
||||
LayoutTransform::create_translation(100.0, 50.0, 0.0),
|
||||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
let child2 = add_reference_frame(
|
||||
&mut cst,
|
||||
Some(child1),
|
||||
LayoutTransform::scale(2.0, 4.0, 1.0),
|
||||
LayoutTransform::create_scale(2.0, 4.0, 1.0),
|
||||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
let child3 = add_reference_frame(
|
||||
&mut cst,
|
||||
Some(child2),
|
||||
LayoutTransform::translation(200.0, -100.0, 0.0),
|
||||
LayoutTransform::create_translation(200.0, -100.0, 0.0),
|
||||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
let child4 = add_reference_frame(
|
||||
&mut cst,
|
||||
Some(child3),
|
||||
LayoutTransform::scale(3.0, 2.0, 1.0),
|
||||
LayoutTransform::create_scale(3.0, 2.0, 1.0),
|
||||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
@ -967,7 +967,7 @@ fn test_cst_translation_rotate() {
|
||||
let child1 = add_reference_frame(
|
||||
&mut cst,
|
||||
Some(root),
|
||||
LayoutTransform::rotation(0.0, 0.0, 1.0, Angle::degrees(-90.0)),
|
||||
LayoutTransform::create_rotation(0.0, 0.0, 1.0, Angle::degrees(90.0)),
|
||||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
|
@ -1222,7 +1222,7 @@ impl TextureCache {
|
||||
&mut self,
|
||||
params: &CacheAllocParams,
|
||||
) -> CacheEntry {
|
||||
assert!(!params.descriptor.size.is_empty());
|
||||
assert!(!params.descriptor.size.is_empty_or_negative());
|
||||
|
||||
// If this image doesn't qualify to go in the shared (batching) cache,
|
||||
// allocate a standalone entry.
|
||||
|
@ -284,7 +284,7 @@ impl ScaleOffset {
|
||||
}
|
||||
|
||||
pub fn to_transform<F, T>(&self) -> Transform3D<f32, F, T> {
|
||||
Transform3D::new(
|
||||
Transform3D::row_major(
|
||||
self.scale.x,
|
||||
0.0,
|
||||
0.0,
|
||||
@ -387,10 +387,13 @@ impl<Src, Dst> MatrixHelpers<Src, Dst> for Transform3D<f32, Src, Dst> {
|
||||
|
||||
fn inverse_project(&self, target: &Point2D<f32, Dst>) -> Option<Point2D<f32, Src>> {
|
||||
let m: Transform2D<f32, Src, Dst>;
|
||||
m = Transform2D::new(
|
||||
self.m11 - target.x * self.m14, self.m12 - target.y * self.m14,
|
||||
self.m21 - target.x * self.m24, self.m22 - target.y * self.m24,
|
||||
self.m41 - target.x * self.m44, self.m42 - target.y * self.m44,
|
||||
m = Transform2D::column_major(
|
||||
self.m11 - target.x * self.m14,
|
||||
self.m21 - target.x * self.m24,
|
||||
self.m41 - target.x * self.m44,
|
||||
self.m12 - target.y * self.m14,
|
||||
self.m22 - target.y * self.m24,
|
||||
self.m42 - target.y * self.m44,
|
||||
);
|
||||
m.inverse().map(|inv| Point2D::new(inv.m31, inv.m32))
|
||||
}
|
||||
@ -473,12 +476,10 @@ impl<Src, Dst> MatrixHelpers<Src, Dst> for Transform3D<f32, Src, Dst> {
|
||||
}
|
||||
|
||||
fn cast_unit<NewSrc, NewDst>(&self) -> Transform3D<f32, NewSrc, NewDst> {
|
||||
Transform3D::new(
|
||||
self.m11, self.m12, self.m13, self.m14,
|
||||
self.m21, self.m22, self.m23, self.m24,
|
||||
self.m31, self.m32, self.m33, self.m34,
|
||||
self.m41, self.m42, self.m43, self.m44,
|
||||
)
|
||||
Transform3D::row_major(self.m11, self.m12, self.m13, self.m14,
|
||||
self.m21, self.m22, self.m23, self.m24,
|
||||
self.m31, self.m32, self.m33, self.m34,
|
||||
self.m41, self.m42, self.m43, self.m44)
|
||||
}
|
||||
}
|
||||
|
||||
@ -605,9 +606,6 @@ pub fn extract_inner_rect_safe<U>(
|
||||
extract_inner_rect_impl(rect, radii, 1.0)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
use euclid::vec3;
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod test {
|
||||
use super::*;
|
||||
@ -621,7 +619,7 @@ pub mod test {
|
||||
let p0 = Point2D::new(1.0, 2.0);
|
||||
// an identical transform doesn't need any inverse projection
|
||||
assert_eq!(m0.inverse_project(&p0), Some(p0));
|
||||
let m1 = Transform3D::rotation(0.0, 1.0, 0.0, Angle::radians(-PI / 3.0));
|
||||
let m1 = Transform3D::create_rotation(0.0, 1.0, 0.0, Angle::radians(PI / 3.0));
|
||||
// rotation by 60 degrees would imply scaling of X component by a factor of 2
|
||||
assert_eq!(m1.inverse_project(&p0), Some(Point2D::new(2.0, 2.0)));
|
||||
}
|
||||
@ -634,18 +632,18 @@ pub mod test {
|
||||
|
||||
#[test]
|
||||
fn scale_offset_convert() {
|
||||
let xref = LayoutTransform::translation(130.0, 200.0, 0.0);
|
||||
let xref = LayoutTransform::create_translation(130.0, 200.0, 0.0);
|
||||
validate_convert(&xref);
|
||||
|
||||
let xref = LayoutTransform::scale(13.0, 8.0, 1.0);
|
||||
let xref = LayoutTransform::create_scale(13.0, 8.0, 1.0);
|
||||
validate_convert(&xref);
|
||||
|
||||
let xref = LayoutTransform::scale(0.5, 0.5, 1.0)
|
||||
let xref = LayoutTransform::create_scale(0.5, 0.5, 1.0)
|
||||
.pre_translate(LayoutVector3D::new(124.0, 38.0, 0.0));
|
||||
validate_convert(&xref);
|
||||
|
||||
let xref = LayoutTransform::scale(30.0, 11.0, 1.0)
|
||||
.then_translate(vec3(50.0, 240.0, 0.0));
|
||||
let xref = LayoutTransform::create_translation(50.0, 240.0, 0.0)
|
||||
.pre_transform(&LayoutTransform::create_scale(30.0, 11.0, 1.0));
|
||||
validate_convert(&xref);
|
||||
}
|
||||
|
||||
@ -662,24 +660,23 @@ pub mod test {
|
||||
|
||||
#[test]
|
||||
fn scale_offset_inverse() {
|
||||
let xref = LayoutTransform::translation(130.0, 200.0, 0.0);
|
||||
let xref = LayoutTransform::create_translation(130.0, 200.0, 0.0);
|
||||
validate_inverse(&xref);
|
||||
|
||||
let xref = LayoutTransform::scale(13.0, 8.0, 1.0);
|
||||
let xref = LayoutTransform::create_scale(13.0, 8.0, 1.0);
|
||||
validate_inverse(&xref);
|
||||
|
||||
let xref = LayoutTransform::translation(124.0, 38.0, 0.0).
|
||||
then_scale(0.5, 0.5, 1.0);
|
||||
|
||||
let xref = LayoutTransform::create_scale(0.5, 0.5, 1.0)
|
||||
.pre_translate(LayoutVector3D::new(124.0, 38.0, 0.0));
|
||||
validate_inverse(&xref);
|
||||
|
||||
let xref = LayoutTransform::scale(30.0, 11.0, 1.0)
|
||||
.then_translate(vec3(50.0, 240.0, 0.0));
|
||||
let xref = LayoutTransform::create_translation(50.0, 240.0, 0.0)
|
||||
.pre_transform(&LayoutTransform::create_scale(30.0, 11.0, 1.0));
|
||||
validate_inverse(&xref);
|
||||
}
|
||||
|
||||
fn validate_accumulate(x0: &LayoutTransform, x1: &LayoutTransform) {
|
||||
let x = x1.then(&x0);
|
||||
let x = x0.pre_transform(x1);
|
||||
|
||||
let s0 = ScaleOffset::from_transform(x0).unwrap();
|
||||
let s1 = ScaleOffset::from_transform(x1).unwrap();
|
||||
@ -691,8 +688,8 @@ pub mod test {
|
||||
|
||||
#[test]
|
||||
fn scale_offset_accumulate() {
|
||||
let x0 = LayoutTransform::translation(130.0, 200.0, 0.0);
|
||||
let x1 = LayoutTransform::scale(7.0, 3.0, 1.0);
|
||||
let x0 = LayoutTransform::create_translation(130.0, 200.0, 0.0);
|
||||
let x1 = LayoutTransform::create_scale(7.0, 3.0, 1.0);
|
||||
|
||||
validate_accumulate(&x0, &x1);
|
||||
}
|
||||
@ -801,7 +798,7 @@ impl<Src, Dst> FastTransform<Src, Dst> {
|
||||
pub fn to_transform(&self) -> Cow<Transform3D<f32, Src, Dst>> {
|
||||
match *self {
|
||||
FastTransform::Offset(offset) => Cow::Owned(
|
||||
Transform3D::translation(offset.x, offset.y, 0.0)
|
||||
Transform3D::create_translation(offset.x, offset.y, 0.0)
|
||||
),
|
||||
FastTransform::Transform { ref transform, .. } => Cow::Borrowed(transform),
|
||||
}
|
||||
@ -820,7 +817,7 @@ impl<Src, Dst> FastTransform<Src, Dst> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn then<NewDst>(&self, other: &FastTransform<Dst, NewDst>) -> FastTransform<Src, NewDst> {
|
||||
pub fn post_transform<NewDst>(&self, other: &FastTransform<Dst, NewDst>) -> FastTransform<Src, NewDst> {
|
||||
match *self {
|
||||
FastTransform::Offset(offset) => match *other {
|
||||
FastTransform::Offset(other_offset) => {
|
||||
@ -838,15 +835,15 @@ impl<Src, Dst> FastTransform<Src, Dst> {
|
||||
FastTransform::Offset(other_offset) => {
|
||||
FastTransform::with_transform(
|
||||
transform
|
||||
.then_translate(other_offset.to_3d())
|
||||
.post_translate(other_offset.to_3d())
|
||||
.with_destination::<NewDst>()
|
||||
)
|
||||
}
|
||||
FastTransform::Transform { transform: ref other_transform, inverse: ref other_inverse, is_2d: other_is_2d } => {
|
||||
FastTransform::Transform {
|
||||
transform: transform.then(other_transform),
|
||||
transform: transform.post_transform(other_transform),
|
||||
inverse: inverse.as_ref().and_then(|self_inv|
|
||||
other_inverse.as_ref().map(|other_inv| other_inv.then(self_inv))
|
||||
other_inverse.as_ref().map(|other_inv| self_inv.pre_transform(other_inv))
|
||||
),
|
||||
is_2d: is_2d & other_is_2d,
|
||||
}
|
||||
@ -859,7 +856,7 @@ impl<Src, Dst> FastTransform<Src, Dst> {
|
||||
&self,
|
||||
other: &FastTransform<NewSrc, Src>
|
||||
) -> FastTransform<NewSrc, Dst> {
|
||||
other.then(self)
|
||||
other.post_transform(self)
|
||||
}
|
||||
|
||||
pub fn pre_translate(&self, other_offset: Vector2D<f32, Src>) -> Self {
|
||||
@ -871,13 +868,13 @@ impl<Src, Dst> FastTransform<Src, Dst> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn then_translate(&self, other_offset: Vector2D<f32, Dst>) -> Self {
|
||||
pub fn post_translate(&self, other_offset: Vector2D<f32, Dst>) -> Self {
|
||||
match *self {
|
||||
FastTransform::Offset(offset) => {
|
||||
FastTransform::Offset(offset + other_offset * Scale::<_, _, Src>::new(1.0))
|
||||
}
|
||||
FastTransform::Transform { ref transform, .. } => {
|
||||
let transform = transform.then_translate(other_offset.to_3d());
|
||||
let transform = transform.post_translate(other_offset.to_3d());
|
||||
FastTransform::with_transform(transform)
|
||||
}
|
||||
}
|
||||
|
@ -476,7 +476,7 @@ pub fn update_primitive_visibility(
|
||||
prim_instance.clip_set.local_clip_rect
|
||||
};
|
||||
|
||||
if combined_local_clip_rect.size.is_empty() {
|
||||
if combined_local_clip_rect.size.is_empty_or_negative() {
|
||||
if prim_instance.is_chased() {
|
||||
println!("\tculled for zero local clip rectangle");
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ app_units = "0.7"
|
||||
bitflags = "1.2"
|
||||
byteorder = "1.2.1"
|
||||
derive_more = "0.99"
|
||||
euclid = { version = "0.22.0", features = ["serde"] }
|
||||
euclid = { version = "0.20.0", features = ["serde"] }
|
||||
malloc_size_of_derive = "0.1"
|
||||
serde = { version = "1.0", features = ["rc"] }
|
||||
serde_derive = "1.0"
|
||||
|
@ -740,23 +740,23 @@ impl Rotation {
|
||||
) -> LayoutTransform {
|
||||
let (shift_center_to_origin, angle) = match self {
|
||||
Rotation::Degree0 => {
|
||||
(LayoutTransform::translation(-size.width / 2., -size.height / 2., 0.), Angle::degrees(0.))
|
||||
(LayoutTransform::create_translation(-size.width / 2., -size.height / 2., 0.), Angle::degrees(0.))
|
||||
},
|
||||
Rotation::Degree90 => {
|
||||
(LayoutTransform::translation(-size.height / 2., -size.width / 2., 0.), Angle::degrees(90.))
|
||||
(LayoutTransform::create_translation(-size.height / 2., -size.width / 2., 0.), Angle::degrees(90.))
|
||||
},
|
||||
Rotation::Degree180 => {
|
||||
(LayoutTransform::translation(-size.width / 2., -size.height / 2., 0.), Angle::degrees(180.))
|
||||
(LayoutTransform::create_translation(-size.width / 2., -size.height / 2., 0.), Angle::degrees(180.))
|
||||
},
|
||||
Rotation::Degree270 => {
|
||||
(LayoutTransform::translation(-size.height / 2., -size.width / 2., 0.), Angle::degrees(270.))
|
||||
(LayoutTransform::create_translation(-size.height / 2., -size.width / 2., 0.), Angle::degrees(270.))
|
||||
},
|
||||
};
|
||||
let shift_origin_to_center = LayoutTransform::translation(size.width / 2., size.height / 2., 0.);
|
||||
let shift_origin_to_center = LayoutTransform::create_translation(size.width / 2., size.height / 2., 0.);
|
||||
|
||||
shift_center_to_origin
|
||||
.then(&LayoutTransform::rotation(0., 0., 1.0, angle))
|
||||
.then(&shift_origin_to_center)
|
||||
LayoutTransform::create_rotation(0., 0., -1.0, angle)
|
||||
.pre_transform(&shift_center_to_origin)
|
||||
.post_transform(&shift_origin_to_center)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -506,9 +506,8 @@ where
|
||||
|
||||
match (*self, *other) {
|
||||
(All, rect) | (rect, All) => rect,
|
||||
(Partial(rect1), Partial(rect2)) => {
|
||||
Partial(rect1.intersection(&rect2).unwrap_or_else(Rect::zero))
|
||||
}
|
||||
(Partial(rect1), Partial(rect2)) => Partial(rect1.intersection(&rect2)
|
||||
.unwrap_or_else(Rect::zero))
|
||||
}
|
||||
}
|
||||
|
||||
@ -517,10 +516,9 @@ where
|
||||
use crate::DirtyRect::*;
|
||||
|
||||
match *self {
|
||||
All => *rect,
|
||||
Partial(dirty_rect) => {
|
||||
dirty_rect.intersection(rect).unwrap_or_else(Rect::zero)
|
||||
}
|
||||
All => *rect,
|
||||
Partial(dirty_rect) => dirty_rect.intersection(rect)
|
||||
.unwrap_or_else(Rect::zero),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -592,12 +592,13 @@ pub fn compute_valid_tiles_if_bounds_change(
|
||||
new_rect: &DeviceIntRect,
|
||||
tile_size: u16,
|
||||
) -> Option<TileRange> {
|
||||
let intersection = match prev_rect.intersection(new_rect) {
|
||||
Some(rect) => rect,
|
||||
None => {
|
||||
return Some(TileRange::zero());
|
||||
}
|
||||
};
|
||||
let intersection = prev_rect.intersection(new_rect);
|
||||
|
||||
if intersection.is_none() {
|
||||
return Some(TileRange::zero());
|
||||
}
|
||||
|
||||
let intersection = intersection.unwrap_or_else(DeviceIntRect::zero);
|
||||
|
||||
let left = prev_rect.min_x() != new_rect.min_x();
|
||||
let right = prev_rect.max_x() != new_rect.max_x();
|
||||
|
@ -291,12 +291,13 @@ fn compute_valid_tiles_if_bounds_change(
|
||||
new_rect: &DeviceIntRect,
|
||||
tile_size: u16,
|
||||
) -> Option<TileRange> {
|
||||
let intersection = match prev_rect.intersection(new_rect) {
|
||||
Some(rect) => rect,
|
||||
None => {
|
||||
return Some(TileRange::zero());
|
||||
}
|
||||
};
|
||||
let intersection = prev_rect.intersection(new_rect);
|
||||
|
||||
if intersection.is_none() {
|
||||
return Some(TileRange::zero());
|
||||
}
|
||||
|
||||
let intersection = intersection.unwrap_or_else(DeviceIntRect::zero);
|
||||
|
||||
let left = prev_rect.min_x() != new_rect.min_x();
|
||||
let right = prev_rect.max_x() != new_rect.max_x();
|
||||
|
@ -11,4 +11,4 @@ path = "lib.rs"
|
||||
|
||||
[dependencies]
|
||||
app_units = "0.7"
|
||||
euclid = "0.22"
|
||||
euclid = "0.20"
|
||||
|
@ -11,7 +11,7 @@ base64 = "0.10"
|
||||
bincode = "1.0"
|
||||
byteorder = "1.0"
|
||||
env_logger = { version = "0.5", optional = true }
|
||||
euclid = "0.22"
|
||||
euclid = "0.20"
|
||||
gleam = "0.12"
|
||||
glutin = "0.21"
|
||||
app_units = "0.7"
|
||||
|
@ -6,7 +6,7 @@
|
||||
root:
|
||||
items:
|
||||
- type: stacking-context
|
||||
transform: rotate-z(-45) rotate-x(-60)
|
||||
transform: rotate-z(45) rotate-x(60)
|
||||
transform-origin: 300 300
|
||||
items:
|
||||
- type: box-shadow
|
||||
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
@ -6,7 +6,7 @@ root:
|
||||
bounds: [0, 0, 0, 0]
|
||||
"clip-rect": [0, 0, 0, 0]
|
||||
type: "stacking-context"
|
||||
transform: rotate(-45) translate(200, 0)
|
||||
transform: rotate(45) translate(200, 0)
|
||||
items:
|
||||
-
|
||||
bounds: [0, 0, 300, 300]
|
||||
@ -23,7 +23,7 @@ root:
|
||||
"clip-rect": [0, 0, 0, 0]
|
||||
clip-and-scroll: 5
|
||||
type: "stacking-context"
|
||||
transform: rotate(45) translate(-300, 0)
|
||||
transform: rotate(-45) translate(-300, 0)
|
||||
items:
|
||||
-
|
||||
bounds: [0, 0, 1598, 1200]
|
||||
|
@ -14,7 +14,7 @@ root:
|
||||
-
|
||||
bounds: [0, 0, 0, 0]
|
||||
type: "stacking-context"
|
||||
transform: rotate(-15) translate(200, 0)
|
||||
transform: rotate(15) translate(200, 0)
|
||||
items:
|
||||
-
|
||||
bounds: [0, 0, 1000, 1000]
|
||||
|
@ -30,7 +30,7 @@ root:
|
||||
-
|
||||
bounds: [0, 0, 200, 200]
|
||||
type: stacking-context
|
||||
transform: rotate(-90)
|
||||
transform: rotate(90)
|
||||
items:
|
||||
- type: clip
|
||||
id: 3
|
||||
|
@ -1,4 +1,4 @@
|
||||
platform(linux,mac) == border-with-rounded-clip.yaml border-with-rounded-clip.png
|
||||
platform(linux,mac) == border-with-rounded-clip.yaml border-with-rounded-clip.png
|
||||
== clip-mode.yaml clip-mode.png
|
||||
== clip-ellipse.yaml clip-ellipse.png
|
||||
platform(linux,mac) == clip-45-degree-rotation.yaml clip-45-degree-rotation-ref.png
|
||||
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
@ -14,7 +14,7 @@ root:
|
||||
bounds: 0 0 256 256
|
||||
- type: stacking-context
|
||||
bounds: 50 50 0 0
|
||||
transform: ["rotate-y(-50)", "rotate-z(-45)"]
|
||||
transform: ["rotate-y(50)", "rotate-z(45)"]
|
||||
items:
|
||||
- type: clip
|
||||
id: 2
|
||||
|
@ -8,7 +8,7 @@ root:
|
||||
clip-rect: 10 0 300 300
|
||||
- type: stacking-context
|
||||
bounds: 30 30 0 0
|
||||
transform: rotate-z(-45)
|
||||
transform: rotate-z(45)
|
||||
filters: drop-shadow([15, 0], 0, red)
|
||||
clip-node: 2
|
||||
items:
|
||||
|
@ -13,7 +13,7 @@ root:
|
||||
items:
|
||||
- type: stacking-context
|
||||
bounds: [50, -10, 200, 100]
|
||||
transform: rotate-z(-90)
|
||||
transform: rotate-z(90)
|
||||
items:
|
||||
-
|
||||
bounds: [0, 0, 500, 150]
|
||||
@ -26,7 +26,7 @@ root:
|
||||
- type: stacking-context
|
||||
bounds: [150, 35, 200, 100]
|
||||
filters: drop-shadow([200, 10], 5, red)
|
||||
transform: rotate-z(-90)
|
||||
transform: rotate-z(90)
|
||||
items:
|
||||
-
|
||||
bounds: [0, 0, 500, 150]
|
||||
|
@ -3,7 +3,7 @@ root:
|
||||
items:
|
||||
- type: stacking-context
|
||||
bounds: [0, 100, 300, 300]
|
||||
transform: scale-x(0.1) rotate-z(-45)
|
||||
transform: scale-x(0.1) rotate-z(45)
|
||||
filter-primitives:
|
||||
- type: blur
|
||||
radius: 10
|
||||
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
@ -8,7 +8,7 @@ root:
|
||||
items:
|
||||
- type: "stacking-context"
|
||||
transform-origin: 0 250
|
||||
transform: rotate-x(-15)
|
||||
transform: rotate-x(15)
|
||||
filter-primitives:
|
||||
- type: drop-shadow
|
||||
color: red
|
||||
|
@ -9,7 +9,7 @@ root:
|
||||
items:
|
||||
- type: stacking-context
|
||||
bounds: [0, 0, 600, 600]
|
||||
transform: rotate-x(-60.0)
|
||||
transform: rotate-x(60.0)
|
||||
items:
|
||||
- type: rect
|
||||
bounds: [000, 0, 600, 600]
|
||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
@ -7,7 +7,7 @@ root:
|
||||
items:
|
||||
- type: "stacking-context"
|
||||
transform-style: preserve-3d
|
||||
transform: rotate-y(-30) rotate-x(-75) translate(-100, 100, 0)
|
||||
transform: rotate-y(30) rotate-x(75) translate(-100, 100, 0)
|
||||
items:
|
||||
- type: "stacking-context"
|
||||
perspective: 400
|
||||
@ -25,7 +25,7 @@ root:
|
||||
color: 255 0 0 1.0000
|
||||
- type: stacking-context
|
||||
bounds: [0, 0, 600, 600]
|
||||
transform: rotate-z(-90)
|
||||
transform: rotate-z(90)
|
||||
items:
|
||||
-
|
||||
bounds: [0, 200, 150, 200]
|
||||
|
@ -10,14 +10,14 @@ root:
|
||||
items:
|
||||
- type: stacking-context
|
||||
bounds: [0, 0, 600, 600]
|
||||
transform: rotate-y(-60.0)
|
||||
transform: rotate-y(60.0)
|
||||
items:
|
||||
- type: rect
|
||||
bounds: [0, 0, 600, 600]
|
||||
color: [255, 0, 0, 0.5]
|
||||
- type: stacking-context
|
||||
bounds: [0, 0, 600, 600]
|
||||
transform: rotate-y(60.0)
|
||||
transform: rotate-y(-60.0)
|
||||
items:
|
||||
- type: rect
|
||||
bounds: [0, 0, 600, 600]
|
||||
|
@ -10,7 +10,7 @@ root:
|
||||
bounds: 0 0 100 100
|
||||
color: red
|
||||
- type: stacking-context
|
||||
transform: rotate-y(-0.1)
|
||||
transform: rotate-y(0.1)
|
||||
bounds: 0 0 100 100
|
||||
items:
|
||||
- type: rect
|
||||
|
@ -2,7 +2,7 @@ root:
|
||||
items:
|
||||
- type: stacking-context
|
||||
bounds: [0, 0, 660, 210]
|
||||
transform: scale(1.5, 2.5) rotate(-10)
|
||||
transform: scale(1.5, 2.5) rotate(10)
|
||||
items:
|
||||
- text: "a Bcd Efgh Ijklm Nopqrs Tuvwxyz"
|
||||
origin: 20 50
|
||||
|
@ -1,7 +1,7 @@
|
||||
root:
|
||||
items:
|
||||
- type: stacking-context
|
||||
transform: scale(5.0) rotate(-45)
|
||||
transform: scale(5.0) rotate(45)
|
||||
transform-origin: 300 300
|
||||
raster-space: local(1.0)
|
||||
items:
|
||||
@ -10,7 +10,7 @@ root:
|
||||
size: 20
|
||||
font: "FreeSans.ttf"
|
||||
- type: stacking-context
|
||||
transform: scale(5.0) rotate(-45)
|
||||
transform: scale(5.0) rotate(45)
|
||||
transform-origin: 0 400
|
||||
items:
|
||||
- text: "Screen"
|
||||
@ -18,7 +18,7 @@ root:
|
||||
size: 20
|
||||
font: "FreeSans.ttf"
|
||||
- type: stacking-context
|
||||
transform: scale(5.0) rotate(-45)
|
||||
transform: scale(5.0) rotate(45)
|
||||
transform-origin: -80 240
|
||||
raster-space: local(5.0)
|
||||
items:
|
||||
|
@ -3,7 +3,7 @@
|
||||
root:
|
||||
items:
|
||||
- type: stacking-context
|
||||
transform: rotate(-30)
|
||||
transform: rotate(30)
|
||||
transform-origin: 80 80
|
||||
items:
|
||||
-
|
||||
@ -38,7 +38,7 @@ root:
|
||||
items:
|
||||
- type: "stacking-context"
|
||||
transform-origin: 235 235
|
||||
transform: rotate-x(-15)
|
||||
transform: rotate-x(15)
|
||||
items:
|
||||
-
|
||||
type: "shadow"
|
||||
|
@ -2,7 +2,7 @@ root:
|
||||
items:
|
||||
- type: stacking-context
|
||||
bounds: [0, 0, 430, 330]
|
||||
transform: rotate(-30)
|
||||
transform: rotate(30)
|
||||
items:
|
||||
- text: "a Bcd Efgh Ijklm Nopqrs Tuvwxyz"
|
||||
origin: 50 200
|
||||
|
@ -2,7 +2,7 @@ root:
|
||||
items:
|
||||
- type: stacking-context
|
||||
bounds: [0, 0, 300, 60]
|
||||
transform: rotate(-90) translate(-120, 160)
|
||||
transform: rotate(90) translate(-120, 160)
|
||||
items:
|
||||
- text: "This is sideways-left"
|
||||
origin: 0 40
|
||||
@ -10,7 +10,7 @@ root:
|
||||
font: "FreeSans.ttf"
|
||||
- type: stacking-context
|
||||
bounds: [0, 0, 300, 60]
|
||||
transform: rotate(90) translate(-90, 120)
|
||||
transform: rotate(-90) translate(-90, 120)
|
||||
items:
|
||||
- text: "This is sideways-right"
|
||||
origin: 0 40
|
||||
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
@ -3,7 +3,7 @@ root:
|
||||
items:
|
||||
- type: stacking-context
|
||||
bounds: [50, 50, 100, 100]
|
||||
transform: rotate(-30)
|
||||
transform: rotate(30)
|
||||
items:
|
||||
- type: border
|
||||
bounds: [ 10, 10, 100, 100 ]
|
||||
|
@ -9,7 +9,7 @@ root:
|
||||
items:
|
||||
-
|
||||
type: "stacking-context"
|
||||
transform: rotate-x(-45) translate(100, 100, 0)
|
||||
transform: rotate-x(45) translate(100, 100, 0)
|
||||
"transform-style": "preserve-3d"
|
||||
items:
|
||||
-
|
||||
|
@ -6,7 +6,7 @@ root:
|
||||
perspective: 20
|
||||
items:
|
||||
- type: stacking-context
|
||||
transform: rotate-z(-45) rotate-x(-45)
|
||||
transform: rotate-z(45) rotate-x(45)
|
||||
filters: drop-shadow([0, 0], 10000, blue)
|
||||
items:
|
||||
- type: rect
|
||||
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
@ -11,7 +11,7 @@ root:
|
||||
bounds: [0, 0, 0, 0]
|
||||
"clip-and-scroll": 3
|
||||
type: "stacking-context"
|
||||
transform: rotate(-45) translate(200, 200)
|
||||
transform: rotate(45) translate(200, 200)
|
||||
items:
|
||||
-
|
||||
bounds: [0, 0, 100, 100]
|
||||
|
@ -10,7 +10,7 @@ root:
|
||||
-
|
||||
bounds: [0, 0, 1000, 1000]
|
||||
type: "stacking-context"
|
||||
transform: rotate-x(30)
|
||||
transform: rotate-x(-30)
|
||||
items:
|
||||
-
|
||||
bounds: [350, 200, 260, 300]
|
||||
|
@ -9,7 +9,7 @@ root:
|
||||
-
|
||||
bounds: [128, 128, 256, 256]
|
||||
type: "stacking-context"
|
||||
transform: rotate-x(-60) rotate-y(-120)
|
||||
transform: rotate-x(60) rotate-y(120)
|
||||
items:
|
||||
-
|
||||
bounds: [128, 128, 256, 256]
|
||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
@ -17,7 +17,7 @@ root:
|
||||
items:
|
||||
-
|
||||
type: "stacking-context"
|
||||
transform: rotate-x(-10)
|
||||
transform: rotate-x(10)
|
||||
transform-origin: 300 300
|
||||
filters: identity
|
||||
items:
|
||||
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
@ -14,7 +14,7 @@ root:
|
||||
-
|
||||
type: "stacking-context"
|
||||
bounds: [0, 0, 250, 100]
|
||||
transform: rotate-y(54)
|
||||
transform: rotate-y(-54)
|
||||
items:
|
||||
-
|
||||
bounds: [0, 0, 128, 128]
|
||||
|
@ -9,7 +9,7 @@ root:
|
||||
-
|
||||
bounds: [0, 0, 1000, 1000]
|
||||
type: "stacking-context"
|
||||
transform: rotate-x(-45)
|
||||
transform: rotate-x(45)
|
||||
items:
|
||||
-
|
||||
bounds: [350, 400, 260, 260]
|
||||
|
@ -3,7 +3,7 @@ root:
|
||||
items:
|
||||
- type: stacking-context
|
||||
bounds: [50, 50, 100, 100]
|
||||
transform: rotate(-30)
|
||||
transform: rotate(30)
|
||||
items:
|
||||
- type: rect
|
||||
bounds: [ 10, 10, 80, 80 ]
|
||||
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
@ -14,4 +14,4 @@ root:
|
||||
bounds: 20 20 200 200
|
||||
color: blue
|
||||
type: stacking-context
|
||||
transform: rotate(-33)
|
||||
transform: rotate(33)
|
||||
|
@ -14,4 +14,4 @@ root:
|
||||
bounds: 20 20 100 100
|
||||
color: blue
|
||||
type: stacking-context
|
||||
transform: rotate(-30)
|
||||
transform: rotate(30)
|
||||
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
@ -44,7 +44,7 @@ root:
|
||||
"backface-visible": true
|
||||
type: "stacking-context"
|
||||
"scroll-policy": scrollable
|
||||
transform: rotate-z(-1)
|
||||
transform: rotate-z(1)
|
||||
"transform-style": flat
|
||||
items:
|
||||
-
|
||||
|
@ -10,13 +10,13 @@ root:
|
||||
items:
|
||||
- type: "stacking-context"
|
||||
transform-origin: 235 235
|
||||
transform: rotate-x(-15)
|
||||
transform: rotate-x(15)
|
||||
items:
|
||||
- image: checkerboard(2, 16, 16)
|
||||
bounds: [100, 100, 260, 260]
|
||||
- type: "stacking-context"
|
||||
transform-origin: 635 235
|
||||
transform: rotate-z(-45)
|
||||
transform: rotate-z(45)
|
||||
items:
|
||||
- image: checkerboard(2, 16, 16)
|
||||
bounds: [500, 100, 260, 260]
|
||||
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
@ -9,14 +9,14 @@ root:
|
||||
items:
|
||||
- type: "stacking-context"
|
||||
transform-origin: 235 235
|
||||
transform: rotate-x(-15)
|
||||
transform: rotate-x(15)
|
||||
filters: identity
|
||||
items:
|
||||
- image: checkerboard(2, 16, 16)
|
||||
bounds: [100, 100, 260, 260]
|
||||
- type: "stacking-context"
|
||||
transform-origin: 635 235
|
||||
transform: rotate-z(-45)
|
||||
transform: rotate-z(45)
|
||||
items:
|
||||
- image: checkerboard(2, 16, 16)
|
||||
bounds: [500, 100, 260, 260]
|
||||
|
@ -6,14 +6,14 @@ root:
|
||||
items:
|
||||
- type: "stacking-context"
|
||||
transform-origin: 235 235
|
||||
transform: rotate-x(-15)
|
||||
transform: rotate-x(15)
|
||||
filters: blur(3)
|
||||
items:
|
||||
- image: checkerboard(2, 16, 16)
|
||||
bounds: [100, 100, 260, 260]
|
||||
- type: "stacking-context"
|
||||
transform-origin: 635 235
|
||||
transform: rotate-z(-45)
|
||||
transform: rotate-z(45)
|
||||
filters: blur(3)
|
||||
items:
|
||||
- image: checkerboard(2, 16, 16)
|
||||
|
@ -172,24 +172,24 @@ fn make_rotation(
|
||||
axis_y: f32,
|
||||
axis_z: f32,
|
||||
) -> LayoutTransform {
|
||||
let pre_transform = LayoutTransform::translation(-origin.x, -origin.y, -0.0);
|
||||
let post_transform = LayoutTransform::translation(origin.x, origin.y, 0.0);
|
||||
let pre_transform = LayoutTransform::create_translation(origin.x, origin.y, 0.0);
|
||||
let post_transform = LayoutTransform::create_translation(-origin.x, -origin.y, -0.0);
|
||||
|
||||
let theta = 2.0f32 * f32::consts::PI - degrees.to_radians();
|
||||
let transform =
|
||||
LayoutTransform::identity().pre_rotate(axis_x, axis_y, axis_z, Angle::radians(theta));
|
||||
|
||||
pre_transform.then(&transform).then(&post_transform)
|
||||
pre_transform.pre_transform(&transform).pre_transform(&post_transform)
|
||||
}
|
||||
|
||||
pub fn make_perspective(
|
||||
origin: LayoutPoint,
|
||||
perspective: f32,
|
||||
) -> LayoutTransform {
|
||||
let pre_transform = LayoutTransform::translation(-origin.x, -origin.y, -0.0);
|
||||
let post_transform = LayoutTransform::translation(origin.x, origin.y, 0.0);
|
||||
let transform = LayoutTransform::perspective(perspective);
|
||||
pre_transform.then(&transform).then(&post_transform)
|
||||
let pre_transform = LayoutTransform::create_translation(origin.x, origin.y, 0.0);
|
||||
let post_transform = LayoutTransform::create_translation(-origin.x, -origin.y, -0.0);
|
||||
let transform = LayoutTransform::create_perspective(perspective);
|
||||
pre_transform.pre_transform(&transform).pre_transform(&post_transform)
|
||||
}
|
||||
|
||||
// Create a skew matrix, specified in degrees.
|
||||
@ -199,7 +199,7 @@ fn make_skew(
|
||||
) -> LayoutTransform {
|
||||
let alpha = Angle::radians(skew_x.to_radians());
|
||||
let beta = Angle::radians(skew_y.to_radians());
|
||||
LayoutTransform::skew(alpha, beta)
|
||||
LayoutTransform::create_skew(alpha, beta)
|
||||
}
|
||||
|
||||
impl YamlHelper for Yaml {
|
||||
@ -327,11 +327,23 @@ impl YamlHelper for Yaml {
|
||||
fn as_matrix4d(&self) -> Option<LayoutTransform> {
|
||||
if let Some(nums) = self.as_vec_f32() {
|
||||
assert_eq!(nums.len(), 16, "expected 16 floats, got '{:?}'", self);
|
||||
Some(LayoutTransform::new(
|
||||
nums[0], nums[1], nums[2], nums[3],
|
||||
nums[4], nums[5], nums[6], nums[7],
|
||||
nums[8], nums[9], nums[10], nums[11],
|
||||
nums[12], nums[13], nums[14], nums[15],
|
||||
Some(LayoutTransform::row_major(
|
||||
nums[0],
|
||||
nums[1],
|
||||
nums[2],
|
||||
nums[3],
|
||||
nums[4],
|
||||
nums[5],
|
||||
nums[6],
|
||||
nums[7],
|
||||
nums[8],
|
||||
nums[9],
|
||||
nums[10],
|
||||
nums[11],
|
||||
nums[12],
|
||||
nums[13],
|
||||
nums[14],
|
||||
nums[15],
|
||||
))
|
||||
} else {
|
||||
None
|
||||
@ -353,7 +365,7 @@ impl YamlHelper for Yaml {
|
||||
let mx = match function {
|
||||
"translate" if args.len() >= 2 => {
|
||||
let z = args.get(2).and_then(|a| a.parse().ok()).unwrap_or(0.);
|
||||
LayoutTransform::translation(
|
||||
LayoutTransform::create_translation(
|
||||
args[0].parse().unwrap(),
|
||||
args[1].parse().unwrap(),
|
||||
z,
|
||||
@ -374,16 +386,16 @@ impl YamlHelper for Yaml {
|
||||
let y = args.get(1).and_then(|a| a.parse().ok()).unwrap_or(x);
|
||||
// Default to no Z scale if unspecified.
|
||||
let z = args.get(2).and_then(|a| a.parse().ok()).unwrap_or(1.0);
|
||||
LayoutTransform::scale(x, y, z)
|
||||
LayoutTransform::create_scale(x, y, z)
|
||||
}
|
||||
"scale-x" if args.len() == 1 => {
|
||||
LayoutTransform::scale(args[0].parse().unwrap(), 1.0, 1.0)
|
||||
LayoutTransform::create_scale(args[0].parse().unwrap(), 1.0, 1.0)
|
||||
}
|
||||
"scale-y" if args.len() == 1 => {
|
||||
LayoutTransform::scale(1.0, args[0].parse().unwrap(), 1.0)
|
||||
LayoutTransform::create_scale(1.0, args[0].parse().unwrap(), 1.0)
|
||||
}
|
||||
"scale-z" if args.len() == 1 => {
|
||||
LayoutTransform::scale(1.0, 1.0, args[0].parse().unwrap())
|
||||
LayoutTransform::create_scale(1.0, 1.0, args[0].parse().unwrap())
|
||||
}
|
||||
"skew" if args.len() >= 1 => {
|
||||
// Default to no Y skew if unspecified.
|
||||
@ -397,14 +409,14 @@ impl YamlHelper for Yaml {
|
||||
make_skew(0.0, args[0].parse().unwrap())
|
||||
}
|
||||
"perspective" if args.len() == 1 => {
|
||||
LayoutTransform::perspective(args[0].parse().unwrap())
|
||||
LayoutTransform::create_perspective(args[0].parse().unwrap())
|
||||
}
|
||||
_ => {
|
||||
println!("unknown function {}", function);
|
||||
break;
|
||||
}
|
||||
};
|
||||
transform = transform.then(&mx);
|
||||
transform = transform.post_transform(&mx);
|
||||
}
|
||||
Some(transform)
|
||||
}
|
||||
@ -412,7 +424,7 @@ impl YamlHelper for Yaml {
|
||||
let transform = array.iter().fold(
|
||||
LayoutTransform::identity(),
|
||||
|u, yaml| match yaml.as_transform(transform_origin) {
|
||||
Some(ref transform) => transform.then(&u),
|
||||
Some(ref transform) => u.pre_transform(transform),
|
||||
None => u,
|
||||
},
|
||||
);
|
||||
|
@ -32,7 +32,7 @@ app_units = "0.7"
|
||||
content-security-policy = { version = "0.4.0", features = ["serde"], optional = true }
|
||||
crossbeam-channel = { version = "0.4", optional = true }
|
||||
cssparser = "0.27"
|
||||
euclid = "0.22"
|
||||
euclid = "0.20"
|
||||
hashglobe = { path = "../hashglobe" }
|
||||
hyper = { version = "0.12", optional = true }
|
||||
hyper_serde = { version = "0.11", optional = true }
|
||||
|
@ -37,7 +37,7 @@ cssparser = "0.27"
|
||||
derive_more = "0.99"
|
||||
new_debug_unreachable = "1.0"
|
||||
encoding_rs = {version = "0.8", optional = true}
|
||||
euclid = "0.22"
|
||||
euclid = "0.20"
|
||||
fallible = { path = "../fallible" }
|
||||
fxhash = "0.2"
|
||||
hashbrown = "0.7"
|
||||
|
@ -76,7 +76,7 @@ pub use self::GenericMatrix3D as Matrix3D;
|
||||
impl<T: Into<f64>> From<Matrix<T>> for Transform3D<f64> {
|
||||
#[inline]
|
||||
fn from(m: Matrix<T>) -> Self {
|
||||
Transform3D::new(
|
||||
Transform3D::row_major(
|
||||
m.a.into(), m.b.into(), 0.0, 0.0,
|
||||
m.c.into(), m.d.into(), 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0,
|
||||
@ -89,7 +89,7 @@ impl<T: Into<f64>> From<Matrix<T>> for Transform3D<f64> {
|
||||
impl<T: Into<f64>> From<Matrix3D<T>> for Transform3D<f64> {
|
||||
#[inline]
|
||||
fn from(m: Matrix3D<T>) -> Self {
|
||||
Transform3D::new(
|
||||
Transform3D::row_major(
|
||||
m.m11.into(), m.m12.into(), m.m13.into(), m.m14.into(),
|
||||
m.m21.into(), m.m22.into(), m.m23.into(), m.m24.into(),
|
||||
m.m31.into(), m.m32.into(), m.m33.into(), m.m34.into(),
|
||||
@ -443,14 +443,15 @@ where
|
||||
use self::TransformOperation::*;
|
||||
use std::f64;
|
||||
|
||||
const TWO_PI: f64 = 2.0f64 * f64::consts::PI;
|
||||
let reference_width = reference_box.map(|v| v.size.width);
|
||||
let reference_height = reference_box.map(|v| v.size.height);
|
||||
let matrix = match *self {
|
||||
Rotate3D(ax, ay, az, theta) => {
|
||||
let theta = theta.radians64();
|
||||
let theta = TWO_PI - theta.radians64();
|
||||
let (ax, ay, az, theta) =
|
||||
get_normalized_vector_and_angle(ax.into(), ay.into(), az.into(), theta);
|
||||
Transform3D::rotation(
|
||||
Transform3D::create_rotation(
|
||||
ax as f64,
|
||||
ay as f64,
|
||||
az as f64,
|
||||
@ -458,56 +459,56 @@ where
|
||||
)
|
||||
},
|
||||
RotateX(theta) => {
|
||||
let theta = euclid::Angle::radians(theta.radians64());
|
||||
Transform3D::rotation(1., 0., 0., theta)
|
||||
let theta = euclid::Angle::radians(TWO_PI - theta.radians64());
|
||||
Transform3D::create_rotation(1., 0., 0., theta)
|
||||
},
|
||||
RotateY(theta) => {
|
||||
let theta = euclid::Angle::radians(theta.radians64());
|
||||
Transform3D::rotation(0., 1., 0., theta)
|
||||
let theta = euclid::Angle::radians(TWO_PI - theta.radians64());
|
||||
Transform3D::create_rotation(0., 1., 0., theta)
|
||||
},
|
||||
RotateZ(theta) | Rotate(theta) => {
|
||||
let theta = euclid::Angle::radians(theta.radians64());
|
||||
Transform3D::rotation(0., 0., 1., theta)
|
||||
let theta = euclid::Angle::radians(TWO_PI - theta.radians64());
|
||||
Transform3D::create_rotation(0., 0., 1., theta)
|
||||
},
|
||||
Perspective(ref d) => {
|
||||
let m = create_perspective_matrix(d.to_pixel_length(None)?);
|
||||
m.cast()
|
||||
},
|
||||
Scale3D(sx, sy, sz) => Transform3D::scale(sx.into(), sy.into(), sz.into()),
|
||||
Scale(sx, sy) => Transform3D::scale(sx.into(), sy.into(), 1.),
|
||||
ScaleX(s) => Transform3D::scale(s.into(), 1., 1.),
|
||||
ScaleY(s) => Transform3D::scale(1., s.into(), 1.),
|
||||
ScaleZ(s) => Transform3D::scale(1., 1., s.into()),
|
||||
Scale3D(sx, sy, sz) => Transform3D::create_scale(sx.into(), sy.into(), sz.into()),
|
||||
Scale(sx, sy) => Transform3D::create_scale(sx.into(), sy.into(), 1.),
|
||||
ScaleX(s) => Transform3D::create_scale(s.into(), 1., 1.),
|
||||
ScaleY(s) => Transform3D::create_scale(1., s.into(), 1.),
|
||||
ScaleZ(s) => Transform3D::create_scale(1., 1., s.into()),
|
||||
Translate3D(ref tx, ref ty, ref tz) => {
|
||||
let tx = tx.to_pixel_length(reference_width)? as f64;
|
||||
let ty = ty.to_pixel_length(reference_height)? as f64;
|
||||
Transform3D::translation(tx, ty, tz.to_pixel_length(None)? as f64)
|
||||
Transform3D::create_translation(tx, ty, tz.to_pixel_length(None)? as f64)
|
||||
},
|
||||
Translate(ref tx, ref ty) => {
|
||||
let tx = tx.to_pixel_length(reference_width)? as f64;
|
||||
let ty = ty.to_pixel_length(reference_height)? as f64;
|
||||
Transform3D::translation(tx, ty, 0.)
|
||||
Transform3D::create_translation(tx, ty, 0.)
|
||||
},
|
||||
TranslateX(ref t) => {
|
||||
let t = t.to_pixel_length(reference_width)? as f64;
|
||||
Transform3D::translation(t, 0., 0.)
|
||||
Transform3D::create_translation(t, 0., 0.)
|
||||
},
|
||||
TranslateY(ref t) => {
|
||||
let t = t.to_pixel_length(reference_height)? as f64;
|
||||
Transform3D::translation(0., t, 0.)
|
||||
Transform3D::create_translation(0., t, 0.)
|
||||
},
|
||||
TranslateZ(ref z) => {
|
||||
Transform3D::translation(0., 0., z.to_pixel_length(None)? as f64)
|
||||
Transform3D::create_translation(0., 0., z.to_pixel_length(None)? as f64)
|
||||
},
|
||||
Skew(theta_x, theta_y) => Transform3D::skew(
|
||||
Skew(theta_x, theta_y) => Transform3D::create_skew(
|
||||
euclid::Angle::radians(theta_x.radians64()),
|
||||
euclid::Angle::radians(theta_y.radians64()),
|
||||
),
|
||||
SkewX(theta) => Transform3D::skew(
|
||||
SkewX(theta) => Transform3D::create_skew(
|
||||
euclid::Angle::radians(theta.radians64()),
|
||||
euclid::Angle::radians(0.),
|
||||
),
|
||||
SkewY(theta) => Transform3D::skew(
|
||||
SkewY(theta) => Transform3D::create_skew(
|
||||
euclid::Angle::radians(0.),
|
||||
euclid::Angle::radians(theta.radians64()),
|
||||
),
|
||||
@ -546,7 +547,7 @@ impl<T: ToMatrix> Transform<T> {
|
||||
let cast_3d_transform = |m: Transform3D<f64>| -> Transform3D<CSSFloat> {
|
||||
use std::{f32, f64};
|
||||
let cast = |v: f64| { v.min(f32::MAX as f64).max(f32::MIN as f64) as f32 };
|
||||
Transform3D::new(
|
||||
Transform3D::row_major(
|
||||
cast(m.m11), cast(m.m12), cast(m.m13), cast(m.m14),
|
||||
cast(m.m21), cast(m.m22), cast(m.m23), cast(m.m24),
|
||||
cast(m.m31), cast(m.m32), cast(m.m33), cast(m.m34),
|
||||
@ -564,7 +565,7 @@ impl<T: ToMatrix> Transform<T> {
|
||||
reference_box: Option<&Rect<ComputedLength>>,
|
||||
) -> Result<(Transform3D<f64>, bool), ()> {
|
||||
// We intentionally use Transform3D<f64> during computation to avoid error propagation
|
||||
// because using f32 to compute triangle functions (e.g. in rotation()) is not
|
||||
// because using f32 to compute triangle functions (e.g. in create_rotation()) is not
|
||||
// accurate enough. In Gecko, we also use "double" to compute the triangle functions.
|
||||
// Therefore, let's use Transform3D<f64> during matrix computation and cast it into f32
|
||||
// in the end.
|
||||
@ -574,7 +575,7 @@ impl<T: ToMatrix> Transform<T> {
|
||||
for operation in &*self.0 {
|
||||
let matrix = operation.to_3d_matrix(reference_box)?;
|
||||
contain_3d |= operation.is_3d();
|
||||
transform = matrix.then(&transform);
|
||||
transform = transform.pre_transform(&matrix);
|
||||
}
|
||||
|
||||
Ok((transform, contain_3d))
|
||||
@ -594,7 +595,7 @@ pub fn create_perspective_matrix(d: CSSFloat) -> Transform3D<CSSFloat> {
|
||||
if d <= 0.0 {
|
||||
Transform3D::identity()
|
||||
} else {
|
||||
Transform3D::perspective(d)
|
||||
Transform3D::create_perspective(d)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ gecko = []
|
||||
app_units = "0.7"
|
||||
bitflags = "1.0"
|
||||
cssparser = "0.27"
|
||||
euclid = "0.22"
|
||||
euclid = "0.20"
|
||||
lazy_static = "1"
|
||||
malloc_size_of = { path = "../malloc_size_of" }
|
||||
malloc_size_of_derive = "0.1"
|
||||
|
@ -6598,7 +6598,7 @@ pub extern "C" fn Servo_ParseTransformIntoMatrix(
|
||||
Err(..) => return false,
|
||||
};
|
||||
|
||||
*result = m.to_array();
|
||||
*result = m.to_row_major_array();
|
||||
*contain_3d = is_3d;
|
||||
true
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ doctest = false
|
||||
byteorder = "1.0"
|
||||
app_units = "0.7"
|
||||
cssparser = "0.27"
|
||||
euclid = "0.22"
|
||||
euclid = "0.20"
|
||||
html5ever = "0.22"
|
||||
parking_lot = "0.10"
|
||||
rayon = "1"
|
||||
|
2
third_party/rust/euclid/.cargo-checksum.json
vendored
@ -1 +1 @@
|
||||
{"files":{"COPYRIGHT":"ec82b96487e9e778ee610c7ab245162464782cfa1f555c2299333f8dbe5c036a","Cargo.toml":"a86dfb641b12e15efe3e2b40a2061c27b9347b38a315700773d7af2c6acccc96","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"62065228e42caebca7e7d7db1204cbb867033de5982ca4009928915e4095f3a3","README.md":"625bec69c76ce5423fdd05cfe46922b2680ec517f97c5854ce34798d1d8a9541","src/angle.rs":"b4b17c16bd135914a6e2ebad54b9cbb8ea475d5992bcb75c397b7813b6f7b8dd","src/approxeq.rs":"8ad9ab7336e1924b0543eb46f975367f4388a4dda91839b7cda7d21eec8991fb","src/approxord.rs":"f1b11ea7603b3dddb0002c7ded934816f5a8bb108e150028b49595b8e3382ac1","src/box2d.rs":"2566d13d8823c13eaab68bbeabe371fa507497d07b3638e5c501cd73cb2a5251","src/box3d.rs":"a96e6b4cbae217095fcbc997db9f7dfafe813d84856bc0a02abbbb6bc881eac7","src/homogen.rs":"57c08e6e5d0bf87c724eb074c624a6557170f9d695ef1ed1a4b2677069dbbaa4","src/length.rs":"6972f49203c0256287dbf5119124ad64e2cf001574995bfaed8cd21e4a19f17c","src/lib.rs":"ebf2023c1e1bd397a4ae135a14657d00757c9ad4094d32d65848a1d5e061df7a","src/macros.rs":"3b475e84d00cceee6c7e96e9f2c97ba15d8dc7f4094efb82c5ed10bd60d86a64","src/num.rs":"27ef5975c2149f4c1a4659ae1dd9fc86618579ec985361130ea9fdc891fcfae3","src/point.rs":"db1beb1e581261a8077669c0a69973c35100163e1b98e6b720b0af331a951345","src/rect.rs":"83ce34da75dc570d8f62700d283adfda419a98ea2d0fc691dedc4389c574dd46","src/rigid.rs":"e9b39039df2882d5b8d5a28305ddb40f7c59a9401af615b842f485a62af12217","src/rotation.rs":"6ed0b5793fdd3d557e98e9523e506786c337c98ae61a3f7773bbd934922803a9","src/scale.rs":"c26ad154ace1647196eb1a19c0c26c22c461322c643c22b9b260392443688299","src/side_offsets.rs":"b795816fe6cc027692bbb5704eebe48d8556619f837ce75de34ca6acf8502ef9","src/size.rs":"17002e23cc424c04d288f65e5f6493759ea7bfb2b0a749131c1a3561d2e3def4","src/transform2d.rs":"505f47b58a96a64804d027d21ebf28c75c80c7d2975760d6d2cadbefb7c4605c","src/transform3d.rs":"e8221391475208af1430ad3a432e972fe45cec68e10103a57af7197f11e034f8","src/translation.rs":"8500a10ed37447fbc41a4a1f554c08095f055c36b4e0a637d7c07505fe2570a2","src/trig.rs":"ab09a8503d04ac1d0d6848d074ac18a22d324184e5bb186bbd4287c977894886","src/vector.rs":"2f573f1587c8f119c45c8822c81d3fe5aa6113cad51be4d19eea73d8058b91dd"},"package":"7ab0e07e345fb061928646949fdf5fb888e5d75a57385e7f5856e45be289e745"}
|
||||
{"files":{"COPYRIGHT":"ec82b96487e9e778ee610c7ab245162464782cfa1f555c2299333f8dbe5c036a","Cargo.toml":"430f53fbae7381f12155805f713f9b9bb08a9e9ffff3a3f4c887163fb4521e7d","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"62065228e42caebca7e7d7db1204cbb867033de5982ca4009928915e4095f3a3","README.md":"625bec69c76ce5423fdd05cfe46922b2680ec517f97c5854ce34798d1d8a9541","src/angle.rs":"b4b17c16bd135914a6e2ebad54b9cbb8ea475d5992bcb75c397b7813b6f7b8dd","src/approxeq.rs":"8ad9ab7336e1924b0543eb46f975367f4388a4dda91839b7cda7d21eec8991fb","src/approxord.rs":"f1b11ea7603b3dddb0002c7ded934816f5a8bb108e150028b49595b8e3382ac1","src/box2d.rs":"0f7ef877183e25e6b769fc91a0d814e0992b0e6d1c16df415ebbd364d2fd2cf7","src/box3d.rs":"54d6e59622957e784e611a23da9612671a530c61cd364313024d750f953a7564","src/homogen.rs":"3aa960fae9b817057013183f543cf2adc042f5867ece1ee78607e2c46bdbcfed","src/length.rs":"67ef01cfba3f70143c57afda39c8bf9990f29111a031a238de328753ccc2c8a4","src/lib.rs":"d0f1ddda70d8bf3913d9c2c49949dd21ced500cbc0c09d7d08c0aa1570f63df5","src/macros.rs":"3b475e84d00cceee6c7e96e9f2c97ba15d8dc7f4094efb82c5ed10bd60d86a64","src/nonempty.rs":"be5ac81321390d71447607de01811cc6420bcd48aa5274f7a298a99674621846","src/num.rs":"2478501dbe545a73a8b964f4713987b86df8ff0af3d1aba0571cbd00a4e9cbaa","src/point.rs":"6d07046f27dd7a18ba8db8988de82c67cfcdd1b8895a70730123338574e47d39","src/rect.rs":"1391359581ba891a35f390ec3900f1e34ce1e4dc5608fe27662655d3bf443d45","src/rigid.rs":"a9717aac4d254299dc3a60a2a32c5c5309044136702d96030533f7639adeb467","src/rotation.rs":"6cfc7f74a90236c53fa55b83eae373146f7b37a8c400f8f820ebfdbcca245245","src/scale.rs":"197d2d4ba5f6a4fe8d5f0b2b6684499a66727129ad27474b85b0d1ffecd38f05","src/side_offsets.rs":"11b84a7dc620cdf2f1877c82b534947ae337734b9075d34e61306be7f458d127","src/size.rs":"5d5703b464207ff362da650008972ca67fbbc79f7193d0d2a1c7a7873221c24c","src/transform2d.rs":"6b2ff21021d7aa1628585650cc66f18f1a5a6aff5f335ae1ec4f63616c54b3cf","src/transform3d.rs":"83ac57ab5a077127fa7eba401dae2e67f2c129a05081b5b5ed09a2166fa9703f","src/translation.rs":"7847306a3a081559f2839baff9d622e58c63fdcb3981c5ef410b6a8eb8e13ab8","src/trig.rs":"ab09a8503d04ac1d0d6848d074ac18a22d324184e5bb186bbd4287c977894886","src/vector.rs":"f895e029e273defac88b47fef4fb27f627553fb05b8d173cf8f75e28818cd580"},"package":"2bb7ef65b3777a325d1eeefefab5b6d4959da54747e33bd6258e789640f307ad"}
|
2
third_party/rust/euclid/Cargo.toml
vendored
@ -13,7 +13,7 @@
|
||||
[package]
|
||||
edition = "2018"
|
||||
name = "euclid"
|
||||
version = "0.22.0"
|
||||
version = "0.20.14"
|
||||
authors = ["The Servo Project Developers"]
|
||||
description = "Geometry primitives"
|
||||
documentation = "https://docs.rs/euclid/"
|
||||
|
132
third_party/rust/euclid/src/box2d.rs
vendored
@ -9,6 +9,7 @@
|
||||
|
||||
use super::UnknownUnit;
|
||||
use crate::approxord::{max, min};
|
||||
use crate::nonempty::NonEmpty;
|
||||
use crate::num::*;
|
||||
use crate::point::{point2, Point2D};
|
||||
use crate::rect::Rect;
|
||||
@ -27,15 +28,15 @@ use core::fmt;
|
||||
use core::hash::{Hash, Hasher};
|
||||
use core::ops::{Add, Div, DivAssign, Mul, MulAssign, Sub};
|
||||
|
||||
/// A 2d axis aligned rectangle represented by its minimum and maximum coordinates.
|
||||
/// An axis aligned rectangle represented by its minimum and maximum coordinates.
|
||||
///
|
||||
/// # Representation
|
||||
///
|
||||
/// This struct is similar to [`Rect`], but stores rectangle as two endpoints
|
||||
/// That struct is similar to the [`Rect`] struct, but stores rectangle as two corners
|
||||
/// instead of origin point and size. Such representation has several advantages over
|
||||
/// [`Rect`] representation:
|
||||
/// - Several operations are more efficient with `Box2D`, including [`intersection`],
|
||||
/// [`union`], and point-in-rect.
|
||||
/// - The representation is more symmetric, since it stores two quantities of the
|
||||
/// same kind (two points) rather than a point and a dimension (width/height).
|
||||
/// - The representation is less susceptible to overflow. With [`Rect`], computation
|
||||
/// of second point can overflow for a large range of values of origin and size.
|
||||
/// However, with `Box2D`, computation of [`size`] cannot overflow if the coordinates
|
||||
@ -44,16 +45,8 @@ use core::ops::{Add, Div, DivAssign, Mul, MulAssign, Sub};
|
||||
/// A known disadvantage of `Box2D` is that translating the rectangle requires translating
|
||||
/// both points, whereas translating [`Rect`] only requires translating one point.
|
||||
///
|
||||
/// # Empty box
|
||||
///
|
||||
/// A box is considered empty (see [`is_empty`]) if any of the following is true:
|
||||
/// - it's area is empty,
|
||||
/// - it's area is negative (`min.x > max.x` or `min.y > max.y`),
|
||||
/// - it contains NaNs.
|
||||
///
|
||||
/// [`Rect`]: struct.Rect.html
|
||||
/// [`intersection`]: #method.intersection
|
||||
/// [`is_empty`]: #method.is_empty
|
||||
/// [`union`]: #method.union
|
||||
/// [`size`]: #method.size
|
||||
#[repr(C)]
|
||||
@ -99,6 +92,16 @@ impl<T: fmt::Debug, U> fmt::Debug for Box2D<T, U> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: fmt::Display, U> fmt::Display for Box2D<T, U> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Box2D(")?;
|
||||
fmt::Display::fmt(&self.min, f)?;
|
||||
write!(f, ", ")?;
|
||||
fmt::Display::fmt(&self.max, f)?;
|
||||
write!(f, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> Box2D<T, U> {
|
||||
/// Constructor.
|
||||
#[inline]
|
||||
@ -120,9 +123,9 @@ where
|
||||
self.max.x < self.min.x || self.max.y < self.min.y
|
||||
}
|
||||
|
||||
/// Returns true if the size is zero, negative or NaN.
|
||||
/// Returns true if the size is zero or negative.
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
pub fn is_empty_or_negative(&self) -> bool {
|
||||
!(self.max.x > self.min.x && self.max.y > self.min.y)
|
||||
}
|
||||
|
||||
@ -148,7 +151,7 @@ where
|
||||
/// nonempty but this box is empty.
|
||||
#[inline]
|
||||
pub fn contains_box(&self, other: &Self) -> bool {
|
||||
other.is_empty()
|
||||
other.is_empty_or_negative()
|
||||
|| (self.min.x <= other.min.x
|
||||
&& other.max.x <= self.max.x
|
||||
&& self.min.y <= other.min.y
|
||||
@ -161,40 +164,36 @@ where
|
||||
T: Copy + PartialOrd,
|
||||
{
|
||||
#[inline]
|
||||
pub fn to_non_empty(&self) -> Option<Self> {
|
||||
if self.is_empty() {
|
||||
pub fn to_non_empty(&self) -> Option<NonEmpty<Self>> {
|
||||
if self.is_empty_or_negative() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(*self)
|
||||
Some(NonEmpty(*self))
|
||||
}
|
||||
|
||||
/// Computes the intersection of two boxes, returning `None` if the boxes do not intersect.
|
||||
#[inline]
|
||||
pub fn intersection(&self, other: &Self) -> Option<Self> {
|
||||
let b = self.intersection_unchecked(other);
|
||||
|
||||
if b.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(b)
|
||||
}
|
||||
|
||||
/// Computes the intersection of two boxes without check whether they do intersect.
|
||||
/// Computes the intersection of two boxes.
|
||||
///
|
||||
/// The result is a negative box if the boxes do not intersect.
|
||||
/// This can be useful for computing the intersection of more than two boxes, as
|
||||
/// it is possible to chain multiple intersection_unchecked calls and check for
|
||||
/// empty/negative result at the end.
|
||||
#[inline]
|
||||
pub fn intersection_unchecked(&self, other: &Self) -> Self {
|
||||
pub fn intersection(&self, other: &Self) -> Self {
|
||||
Box2D {
|
||||
min: point2(max(self.min.x, other.min.x), max(self.min.y, other.min.y)),
|
||||
max: point2(min(self.max.x, other.max.x), min(self.max.y, other.max.y)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Computes the intersection of two boxes, returning `None` if the boxes do not intersect.
|
||||
#[inline]
|
||||
pub fn try_intersection(&self, other: &Self) -> Option<NonEmpty<Self>> {
|
||||
let intersection = self.intersection(other);
|
||||
|
||||
if intersection.is_negative() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(NonEmpty(intersection))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn union(&self, other: &Self) -> Self {
|
||||
Box2D {
|
||||
@ -373,68 +372,79 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Mul, U> Mul<T> for Box2D<T, U> {
|
||||
impl<T, U> Box2D<T, U>
|
||||
where
|
||||
T: PartialEq,
|
||||
{
|
||||
/// Returns true if the size is zero.
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.min.x == self.max.x || self.min.y == self.max.y
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone + Mul, U> Mul<T> for Box2D<T, U> {
|
||||
type Output = Box2D<T::Output, U>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, scale: T) -> Self::Output {
|
||||
Box2D::new(self.min * scale, self.max * scale)
|
||||
Box2D::new(self.min * scale.clone(), self.max * scale)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + MulAssign, U> MulAssign<T> for Box2D<T, U> {
|
||||
impl<T: Clone + MulAssign, U> MulAssign<T> for Box2D<T, U> {
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, scale: T) {
|
||||
*self *= Scale::new(scale);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Div, U> Div<T> for Box2D<T, U> {
|
||||
impl<T: Clone + Div, U> Div<T> for Box2D<T, U> {
|
||||
type Output = Box2D<T::Output, U>;
|
||||
|
||||
#[inline]
|
||||
fn div(self, scale: T) -> Self::Output {
|
||||
Box2D::new(self.min / scale, self.max / scale)
|
||||
Box2D::new(self.min / scale.clone(), self.max / scale)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + DivAssign, U> DivAssign<T> for Box2D<T, U> {
|
||||
impl<T: Clone + DivAssign, U> DivAssign<T> for Box2D<T, U> {
|
||||
#[inline]
|
||||
fn div_assign(&mut self, scale: T) {
|
||||
*self /= Scale::new(scale);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Box2D<T, U1> {
|
||||
impl<T: Clone + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Box2D<T, U1> {
|
||||
type Output = Box2D<T::Output, U2>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, scale: Scale<T, U1, U2>) -> Self::Output {
|
||||
Box2D::new(self.min * scale, self.max * scale)
|
||||
Box2D::new(self.min * scale.clone(), self.max * scale)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + MulAssign, U> MulAssign<Scale<T, U, U>> for Box2D<T, U> {
|
||||
impl<T: Clone + MulAssign, U> MulAssign<Scale<T, U, U>> for Box2D<T, U> {
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, scale: Scale<T, U, U>) {
|
||||
self.min *= scale;
|
||||
self.min *= scale.clone();
|
||||
self.max *= scale;
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Div, U1, U2> Div<Scale<T, U1, U2>> for Box2D<T, U2> {
|
||||
impl<T: Clone + Div, U1, U2> Div<Scale<T, U1, U2>> for Box2D<T, U2> {
|
||||
type Output = Box2D<T::Output, U1>;
|
||||
|
||||
#[inline]
|
||||
fn div(self, scale: Scale<T, U1, U2>) -> Self::Output {
|
||||
Box2D::new(self.min / scale, self.max / scale)
|
||||
Box2D::new(self.min / scale.clone(), self.max / scale)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + DivAssign, U> DivAssign<Scale<T, U, U>> for Box2D<T, U> {
|
||||
impl<T: Clone + DivAssign, U> DivAssign<Scale<T, U, U>> for Box2D<T, U> {
|
||||
#[inline]
|
||||
fn div_assign(&mut self, scale: Scale<T, U, U>) {
|
||||
self.min /= scale;
|
||||
self.min /= scale.clone();
|
||||
self.max /= scale;
|
||||
}
|
||||
}
|
||||
@ -663,7 +673,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_round() {
|
||||
let b = Box2D::from_points(&[point2(-25.5, -40.4), point2(60.3, 36.5)]).round();
|
||||
assert_eq!(b.min.x, -25.0);
|
||||
assert_eq!(b.min.x, -26.0);
|
||||
assert_eq!(b.min.y, -40.0);
|
||||
assert_eq!(b.max.x, 60.0);
|
||||
assert_eq!(b.max.y, 37.0);
|
||||
@ -732,10 +742,10 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_intersection_unchecked() {
|
||||
fn test_intersection() {
|
||||
let b1 = Box2D::from_points(&[point2(-15.0, -20.0), point2(10.0, 20.0)]);
|
||||
let b2 = Box2D::from_points(&[point2(-10.0, 20.0), point2(15.0, -20.0)]);
|
||||
let b = b1.intersection_unchecked(&b2);
|
||||
let b = b1.intersection(&b2);
|
||||
assert_eq!(b.max.x, 10.0);
|
||||
assert_eq!(b.max.y, 20.0);
|
||||
assert_eq!(b.min.x, -10.0);
|
||||
@ -743,14 +753,14 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_intersection() {
|
||||
fn test_try_intersection() {
|
||||
let b1 = Box2D::from_points(&[point2(-15.0, -20.0), point2(10.0, 20.0)]);
|
||||
let b2 = Box2D::from_points(&[point2(-10.0, 20.0), point2(15.0, -20.0)]);
|
||||
assert!(b1.intersection(&b2).is_some());
|
||||
assert!(b1.try_intersection(&b2).is_some());
|
||||
|
||||
let b1 = Box2D::from_points(&[point2(-15.0, -20.0), point2(-10.0, 20.0)]);
|
||||
let b2 = Box2D::from_points(&[point2(10.0, 20.0), point2(15.0, -20.0)]);
|
||||
assert!(b1.intersection(&b2).is_none());
|
||||
assert!(b1.try_intersection(&b2).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -808,11 +818,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nan_empty() {
|
||||
fn test_nan_empty_or_negative() {
|
||||
use std::f32::NAN;
|
||||
assert!(Box2D { min: point2(NAN, 2.0), max: point2(1.0, 3.0) }.is_empty());
|
||||
assert!(Box2D { min: point2(0.0, NAN), max: point2(1.0, 2.0) }.is_empty());
|
||||
assert!(Box2D { min: point2(1.0, -2.0), max: point2(NAN, 2.0) }.is_empty());
|
||||
assert!(Box2D { min: point2(1.0, -2.0), max: point2(0.0, NAN) }.is_empty());
|
||||
assert!(Box2D { min: point2(NAN, 2.0), max: point2(1.0, 3.0) }.is_empty_or_negative());
|
||||
assert!(Box2D { min: point2(0.0, NAN), max: point2(1.0, 2.0) }.is_empty_or_negative());
|
||||
assert!(Box2D { min: point2(1.0, -2.0), max: point2(NAN, 2.0) }.is_empty_or_negative());
|
||||
assert!(Box2D { min: point2(1.0, -2.0), max: point2(0.0, NAN) }.is_empty_or_negative());
|
||||
}
|
||||
}
|
||||
|
90
third_party/rust/euclid/src/box3d.rs
vendored
@ -9,6 +9,7 @@
|
||||
|
||||
use super::UnknownUnit;
|
||||
use crate::approxord::{max, min};
|
||||
use crate::nonempty::NonEmpty;
|
||||
use crate::num::*;
|
||||
use crate::point::{point3, Point3D};
|
||||
use crate::scale::Scale;
|
||||
@ -69,6 +70,16 @@ impl<T: fmt::Debug, U> fmt::Debug for Box3D<T, U> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: fmt::Display, U> fmt::Display for Box3D<T, U> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Box3D(")?;
|
||||
fmt::Display::fmt(&self.min, f)?;
|
||||
write!(f, ", ")?;
|
||||
fmt::Display::fmt(&self.max, f)?;
|
||||
write!(f, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> Box3D<T, U> {
|
||||
/// Constructor.
|
||||
#[inline]
|
||||
@ -90,9 +101,9 @@ where
|
||||
self.max.x < self.min.x || self.max.y < self.min.y || self.max.z < self.min.z
|
||||
}
|
||||
|
||||
/// Returns true if the size is zero, negative or NaN.
|
||||
/// Returns true if the size is zero or negative.
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
pub fn is_empty_or_negative(&self) -> bool {
|
||||
!(self.max.x > self.min.x && self.max.y > self.min.y && self.max.z > self.min.z)
|
||||
}
|
||||
|
||||
@ -124,7 +135,7 @@ where
|
||||
/// nonempty but this box3d is empty.
|
||||
#[inline]
|
||||
pub fn contains_box(&self, other: &Self) -> bool {
|
||||
other.is_empty()
|
||||
other.is_empty_or_negative()
|
||||
|| (self.min.x <= other.min.x
|
||||
&& other.max.x <= self.max.x
|
||||
&& self.min.y <= other.min.y
|
||||
@ -139,26 +150,24 @@ where
|
||||
T: Copy + PartialOrd,
|
||||
{
|
||||
#[inline]
|
||||
pub fn to_non_empty(&self) -> Option<Self> {
|
||||
if self.is_empty() {
|
||||
pub fn to_non_empty(&self) -> Option<NonEmpty<Self>> {
|
||||
if self.is_empty_or_negative() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(*self)
|
||||
Some(NonEmpty(*self))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn intersection(&self, other: &Self) -> Option<Self> {
|
||||
let b = self.intersection_unchecked(other);
|
||||
|
||||
if b.is_empty() {
|
||||
pub fn try_intersection(&self, other: &Self) -> Option<NonEmpty<Self>> {
|
||||
if !self.intersects(other) {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(b)
|
||||
Some(NonEmpty(self.intersection(other)))
|
||||
}
|
||||
|
||||
pub fn intersection_unchecked(&self, other: &Self) -> Self {
|
||||
pub fn intersection(&self, other: &Self) -> Self {
|
||||
let intersection_min = Point3D::new(
|
||||
max(self.min.x, other.min.x),
|
||||
max(self.min.y, other.min.y),
|
||||
@ -366,24 +375,35 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Mul, U> Mul<T> for Box3D<T, U> {
|
||||
impl<T, U> Box3D<T, U>
|
||||
where
|
||||
T: PartialEq,
|
||||
{
|
||||
/// Returns true if the volume is zero.
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.min.x == self.max.x || self.min.y == self.max.y || self.min.z == self.max.z
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone + Mul, U> Mul<T> for Box3D<T, U> {
|
||||
type Output = Box3D<T::Output, U>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, scale: T) -> Self::Output {
|
||||
Box3D::new(self.min * scale, self.max * scale)
|
||||
Box3D::new(self.min * scale.clone(), self.max * scale)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + MulAssign, U> MulAssign<T> for Box3D<T, U> {
|
||||
impl<T: Clone + MulAssign, U> MulAssign<T> for Box3D<T, U> {
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, scale: T) {
|
||||
self.min *= scale;
|
||||
self.min *= scale.clone();
|
||||
self.max *= scale;
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Div, U> Div<T> for Box3D<T, U> {
|
||||
impl<T: Clone + Div, U> Div<T> for Box3D<T, U> {
|
||||
type Output = Box3D<T::Output, U>;
|
||||
|
||||
#[inline]
|
||||
@ -392,15 +412,15 @@ impl<T: Copy + Div, U> Div<T> for Box3D<T, U> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + DivAssign, U> DivAssign<T> for Box3D<T, U> {
|
||||
impl<T: Clone + DivAssign, U> DivAssign<T> for Box3D<T, U> {
|
||||
#[inline]
|
||||
fn div_assign(&mut self, scale: T) {
|
||||
self.min /= scale;
|
||||
self.min /= scale.clone();
|
||||
self.max /= scale;
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Box3D<T, U1> {
|
||||
impl<T: Clone + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Box3D<T, U1> {
|
||||
type Output = Box3D<T::Output, U2>;
|
||||
|
||||
#[inline]
|
||||
@ -409,7 +429,7 @@ impl<T: Copy + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Box3D<T, U1> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + MulAssign, U> MulAssign<Scale<T, U, U>> for Box3D<T, U> {
|
||||
impl<T: Clone + MulAssign, U> MulAssign<Scale<T, U, U>> for Box3D<T, U> {
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, scale: Scale<T, U, U>) {
|
||||
self.min *= scale.clone();
|
||||
@ -417,7 +437,7 @@ impl<T: Copy + MulAssign, U> MulAssign<Scale<T, U, U>> for Box3D<T, U> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Div, U1, U2> Div<Scale<T, U1, U2>> for Box3D<T, U2> {
|
||||
impl<T: Clone + Div, U1, U2> Div<Scale<T, U1, U2>> for Box3D<T, U2> {
|
||||
type Output = Box3D<T::Output, U1>;
|
||||
|
||||
#[inline]
|
||||
@ -426,7 +446,7 @@ impl<T: Copy + Div, U1, U2> Div<Scale<T, U1, U2>> for Box3D<T, U2> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + DivAssign, U> DivAssign<Scale<T, U, U>> for Box3D<T, U> {
|
||||
impl<T: Clone + DivAssign, U> DivAssign<Scale<T, U, U>> for Box3D<T, U> {
|
||||
#[inline]
|
||||
fn div_assign(&mut self, scale: Scale<T, U, U>) {
|
||||
self.min /= scale.clone();
|
||||
@ -718,7 +738,7 @@ mod tests {
|
||||
fn test_round() {
|
||||
let b =
|
||||
Box3D::from_points(&[point3(-25.5, -40.4, -70.9), point3(60.3, 36.5, 89.8)]).round();
|
||||
assert!(b.min.x == -25.0);
|
||||
assert!(b.min.x == -26.0);
|
||||
assert!(b.min.y == -40.0);
|
||||
assert!(b.min.z == -71.0);
|
||||
assert!(b.max.x == 60.0);
|
||||
@ -775,10 +795,10 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_intersection_unchecked() {
|
||||
fn test_intersection() {
|
||||
let b1 = Box3D::from_points(&[point3(-15.0, -20.0, -20.0), point3(10.0, 20.0, 20.0)]);
|
||||
let b2 = Box3D::from_points(&[point3(-10.0, 20.0, 20.0), point3(15.0, -20.0, -20.0)]);
|
||||
let b = b1.intersection_unchecked(&b2);
|
||||
let b = b1.intersection(&b2);
|
||||
assert!(b.max.x == 10.0);
|
||||
assert!(b.max.y == 20.0);
|
||||
assert!(b.max.z == 20.0);
|
||||
@ -789,14 +809,14 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_intersection() {
|
||||
fn test_try_intersection() {
|
||||
let b1 = Box3D::from_points(&[point3(-15.0, -20.0, -20.0), point3(10.0, 20.0, 20.0)]);
|
||||
let b2 = Box3D::from_points(&[point3(-10.0, 20.0, 20.0), point3(15.0, -20.0, -20.0)]);
|
||||
assert!(b1.intersection(&b2).is_some());
|
||||
assert!(b1.try_intersection(&b2).is_some());
|
||||
|
||||
let b1 = Box3D::from_points(&[point3(-15.0, -20.0, -20.0), point3(-10.0, 20.0, 20.0)]);
|
||||
let b2 = Box3D::from_points(&[point3(10.0, 20.0, 20.0), point3(15.0, -20.0, -20.0)]);
|
||||
assert!(b1.intersection(&b2).is_none());
|
||||
assert!(b1.try_intersection(&b2).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -871,11 +891,11 @@ mod tests {
|
||||
#[test]
|
||||
fn test_nan_empty_or_negative() {
|
||||
use std::f32::NAN;
|
||||
assert!(Box3D { min: point3(NAN, 2.0, 1.0), max: point3(1.0, 3.0, 5.0) }.is_empty());
|
||||
assert!(Box3D { min: point3(0.0, NAN, 1.0), max: point3(1.0, 2.0, 5.0) }.is_empty());
|
||||
assert!(Box3D { min: point3(1.0, -2.0, NAN), max: point3(3.0, 2.0, 5.0) }.is_empty());
|
||||
assert!(Box3D { min: point3(1.0, -2.0, 1.0), max: point3(NAN, 2.0, 5.0) }.is_empty());
|
||||
assert!(Box3D { min: point3(1.0, -2.0, 1.0), max: point3(0.0, NAN, 5.0) }.is_empty());
|
||||
assert!(Box3D { min: point3(1.0, -2.0, 1.0), max: point3(0.0, 1.0, NAN) }.is_empty());
|
||||
assert!(Box3D { min: point3(NAN, 2.0, 1.0), max: point3(1.0, 3.0, 5.0) }.is_empty_or_negative());
|
||||
assert!(Box3D { min: point3(0.0, NAN, 1.0), max: point3(1.0, 2.0, 5.0) }.is_empty_or_negative());
|
||||
assert!(Box3D { min: point3(1.0, -2.0, NAN), max: point3(3.0, 2.0, 5.0) }.is_empty_or_negative());
|
||||
assert!(Box3D { min: point3(1.0, -2.0, 1.0), max: point3(NAN, 2.0, 5.0) }.is_empty_or_negative());
|
||||
assert!(Box3D { min: point3(1.0, -2.0, 1.0), max: point3(0.0, NAN, 5.0) }.is_empty_or_negative());
|
||||
assert!(Box3D { min: point3(1.0, -2.0, 1.0), max: point3(0.0, 1.0, NAN) }.is_empty_or_negative());
|
||||
}
|
||||
}
|
||||
|
18
third_party/rust/euclid/src/homogen.rs
vendored
@ -120,7 +120,7 @@ impl<T: Copy + Div<T, Output = T> + Zero + PartialOrd, U> HomogeneousVector<T, U
|
||||
///
|
||||
/// Returns None if the point is on or behind the W=0 hemisphere.
|
||||
#[inline]
|
||||
pub fn to_point2d(self) -> Option<Point2D<T, U>> {
|
||||
pub fn to_point2d(&self) -> Option<Point2D<T, U>> {
|
||||
if self.w > T::zero() {
|
||||
Some(Point2D::new(self.x / self.w, self.y / self.w))
|
||||
} else {
|
||||
@ -132,7 +132,7 @@ impl<T: Copy + Div<T, Output = T> + Zero + PartialOrd, U> HomogeneousVector<T, U
|
||||
///
|
||||
/// Returns None if the point is on or behind the W=0 hemisphere.
|
||||
#[inline]
|
||||
pub fn to_point3d(self) -> Option<Point3D<T, U>> {
|
||||
pub fn to_point3d(&self) -> Option<Point3D<T, U>> {
|
||||
if self.w > T::zero() {
|
||||
Some(Point3D::new(
|
||||
self.x / self.w,
|
||||
@ -184,6 +184,20 @@ impl<T: fmt::Debug, U> fmt::Debug for HomogeneousVector<T, U> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: fmt::Display, U> fmt::Display for HomogeneousVector<T, U> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "(")?;
|
||||
fmt::Display::fmt(&self.x, f)?;
|
||||
write!(f, ",")?;
|
||||
fmt::Display::fmt(&self.y, f)?;
|
||||
write!(f, ",")?;
|
||||
fmt::Display::fmt(&self.z, f)?;
|
||||
write!(f, ",")?;
|
||||
fmt::Display::fmt(&self.w, f)?;
|
||||
write!(f, ")")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod homogeneous {
|
||||
use super::HomogeneousVector;
|
||||
|
52
third_party/rust/euclid/src/length.rs
vendored
@ -11,7 +11,6 @@
|
||||
use crate::approxeq::ApproxEq;
|
||||
use crate::num::Zero;
|
||||
use crate::scale::Scale;
|
||||
use crate::approxord::{max, min};
|
||||
|
||||
use crate::num::One;
|
||||
use core::cmp::Ordering;
|
||||
@ -83,15 +82,15 @@ impl<T, U> Length<T, U> {
|
||||
}
|
||||
|
||||
impl<T: Clone, U> Length<T, U> {
|
||||
/// Unpack the underlying value from the wrapper.
|
||||
pub fn get(self) -> T {
|
||||
self.0
|
||||
/// Unpack the underlying value from the wrapper, cloning it.
|
||||
pub fn get(&self) -> T {
|
||||
self.0.clone()
|
||||
}
|
||||
|
||||
/// Cast the unit
|
||||
#[inline]
|
||||
pub fn cast_unit<V>(self) -> Length<T, V> {
|
||||
Length::new(self.0)
|
||||
pub fn cast_unit<V>(&self) -> Length<T, V> {
|
||||
Length::new(self.0.clone())
|
||||
}
|
||||
|
||||
/// Linearly interpolate between this length and another length.
|
||||
@ -111,7 +110,7 @@ impl<T: Clone, U> Length<T, U> {
|
||||
/// assert_eq!(from.lerp(to, 2.0), Length::new(16.0));
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn lerp(self, other: Self, t: T) -> Self
|
||||
pub fn lerp(&self, other: Self, t: T) -> Self
|
||||
where
|
||||
T: One + Sub<Output = T> + Mul<Output = T> + Add<Output = T>,
|
||||
{
|
||||
@ -120,30 +119,16 @@ impl<T: Clone, U> Length<T, U> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PartialOrd, U> Length<T, U> {
|
||||
/// Returns minimum between this length and another length.
|
||||
#[inline]
|
||||
pub fn min(self, other: Self) -> Self {
|
||||
min(self, other)
|
||||
}
|
||||
|
||||
/// Returns maximum between this length and another length.
|
||||
#[inline]
|
||||
pub fn max(self, other: Self) -> Self {
|
||||
max(self, other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: NumCast + Clone, U> Length<T, U> {
|
||||
/// Cast from one numeric representation to another, preserving the units.
|
||||
#[inline]
|
||||
pub fn cast<NewT: NumCast>(self) -> Length<NewT, U> {
|
||||
pub fn cast<NewT: NumCast>(&self) -> Length<NewT, U> {
|
||||
self.try_cast().unwrap()
|
||||
}
|
||||
|
||||
/// Fallible cast from one numeric representation to another, preserving the units.
|
||||
pub fn try_cast<NewT: NumCast>(self) -> Option<Length<NewT, U>> {
|
||||
NumCast::from(self.0).map(Length::new)
|
||||
pub fn try_cast<NewT: NumCast>(&self) -> Option<Length<NewT, U>> {
|
||||
NumCast::from(self.get()).map(Length::new)
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,6 +138,12 @@ impl<T: fmt::Debug, U> fmt::Debug for Length<T, U> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: fmt::Display, U> fmt::Display for Length<T, U> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default, U> Default for Length<T, U> {
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
@ -367,6 +358,19 @@ mod tests {
|
||||
assert_eq!(variable_length.get(), 24.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_clones_length_value() {
|
||||
// Calling get returns a clone of the Length's value.
|
||||
// To test this, we need something clone-able - hence a vector.
|
||||
let mut length: Length<Vec<i32>, Inch> = Length::new(vec![1, 2, 3]);
|
||||
|
||||
let value = length.get();
|
||||
length.0.push(4);
|
||||
|
||||
assert_eq!(value, vec![1, 2, 3]);
|
||||
assert_eq!(length.get(), vec![1, 2, 3, 4]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add() {
|
||||
let length1: Length<u8, Mm> = Length::new(250);
|
||||
|
2
third_party/rust/euclid/src/lib.rs
vendored
@ -44,6 +44,7 @@ pub use crate::angle::Angle;
|
||||
pub use crate::box2d::Box2D;
|
||||
pub use crate::homogen::HomogeneousVector;
|
||||
pub use crate::length::Length;
|
||||
pub use crate::nonempty::NonEmpty;
|
||||
pub use crate::point::{point2, point3, Point2D, Point3D};
|
||||
pub use crate::scale::Scale;
|
||||
pub use crate::transform2d::Transform2D;
|
||||
@ -70,6 +71,7 @@ mod box2d;
|
||||
mod box3d;
|
||||
mod homogen;
|
||||
mod length;
|
||||
mod nonempty;
|
||||
pub mod num;
|
||||
mod point;
|
||||
mod rect;
|
||||
|
250
third_party/rust/euclid/src/nonempty.rs
vendored
Normal file
@ -0,0 +1,250 @@
|
||||
use crate::{Box2D, Box3D, Rect, Vector2D, Vector3D};
|
||||
use core::cmp::PartialEq;
|
||||
use core::ops::Deref;
|
||||
use core::ops::{Add, Sub};
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(transparent))]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct NonEmpty<T>(pub(crate) T);
|
||||
|
||||
impl<T> Deref for NonEmpty<T> {
|
||||
type Target = T;
|
||||
fn deref(&self) -> &T {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> NonEmpty<T> {
|
||||
#[inline]
|
||||
pub fn get(&self) -> &T {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> NonEmpty<Rect<T, U>>
|
||||
where
|
||||
T: Copy + PartialOrd + Add<T, Output = T> + Sub<T, Output = T>,
|
||||
{
|
||||
#[inline]
|
||||
pub fn union(&self, other: &Self) -> Self {
|
||||
NonEmpty(self.0.to_box2d().union(&other.0.to_box2d()).to_rect())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn contains_rect(&self, rect: &Self) -> bool {
|
||||
self.min_x() <= rect.min_x()
|
||||
&& rect.max_x() <= self.max_x()
|
||||
&& self.min_y() <= rect.min_y()
|
||||
&& rect.max_y() <= self.max_y()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn translate(&self, by: Vector2D<T, U>) -> Self {
|
||||
NonEmpty(self.0.translate(by))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> NonEmpty<Box2D<T, U>>
|
||||
where
|
||||
T: Copy + PartialOrd,
|
||||
{
|
||||
#[inline]
|
||||
pub fn union(&self, other: &Self) -> Self {
|
||||
NonEmpty(self.0.union(&other.0))
|
||||
}
|
||||
|
||||
/// Returns true if this box contains the interior of the other box.
|
||||
#[inline]
|
||||
pub fn contains_box(&self, other: &Self) -> bool {
|
||||
self.min.x <= other.min.x
|
||||
&& other.max.x <= self.max.x
|
||||
&& self.min.y <= other.min.y
|
||||
&& other.max.y <= self.max.y
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> NonEmpty<Box2D<T, U>>
|
||||
where
|
||||
T: Copy + Add<T, Output = T>,
|
||||
{
|
||||
#[inline]
|
||||
pub fn translate(&self, by: Vector2D<T, U>) -> Self {
|
||||
NonEmpty(self.0.translate(by))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> NonEmpty<Box3D<T, U>>
|
||||
where
|
||||
T: Copy + PartialOrd,
|
||||
{
|
||||
#[inline]
|
||||
pub fn union(&self, other: &Self) -> Self {
|
||||
NonEmpty(self.0.union(&other.0))
|
||||
}
|
||||
|
||||
/// Returns true if this box contains the interior of the other box.
|
||||
#[inline]
|
||||
pub fn contains_box(&self, other: &Self) -> bool {
|
||||
self.min.x <= other.min.x
|
||||
&& other.max.x <= self.max.x
|
||||
&& self.min.y <= other.min.y
|
||||
&& other.max.y <= self.max.y
|
||||
&& self.min.z <= other.min.z
|
||||
&& other.max.z <= self.max.z
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> NonEmpty<Box3D<T, U>>
|
||||
where
|
||||
T: Copy + Add<T, Output = T>,
|
||||
{
|
||||
#[inline]
|
||||
pub fn translate(&self, by: Vector3D<T, U>) -> Self {
|
||||
NonEmpty(self.0.translate(by))
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_nonempty() {
|
||||
use crate::default;
|
||||
use crate::point2;
|
||||
|
||||
// zero-width
|
||||
let box1: default::Box2D<i32> = Box2D {
|
||||
min: point2(-10, 2),
|
||||
max: point2(-10, 12),
|
||||
};
|
||||
// zero-height
|
||||
let box2: default::Box2D<i32> = Box2D {
|
||||
min: point2(0, 11),
|
||||
max: point2(2, 11),
|
||||
};
|
||||
// negative width
|
||||
let box3: default::Box2D<i32> = Box2D {
|
||||
min: point2(1, 11),
|
||||
max: point2(0, 12),
|
||||
};
|
||||
// negative height
|
||||
let box4: default::Box2D<i32> = Box2D {
|
||||
min: point2(0, 11),
|
||||
max: point2(5, 10),
|
||||
};
|
||||
|
||||
assert!(box1.to_non_empty().is_none());
|
||||
assert!(box2.to_non_empty().is_none());
|
||||
assert!(box3.to_non_empty().is_none());
|
||||
assert!(box4.to_non_empty().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nonempty_union() {
|
||||
use crate::default;
|
||||
use crate::{point2, point3, size2};
|
||||
|
||||
let box1: default::Box2D<i32> = Box2D {
|
||||
min: point2(-10, 2),
|
||||
max: point2(15, 12),
|
||||
};
|
||||
let box2 = Box2D {
|
||||
min: point2(-2, -5),
|
||||
max: point2(10, 5),
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
box1.union(&box2),
|
||||
*box1
|
||||
.to_non_empty()
|
||||
.unwrap()
|
||||
.union(&box2.to_non_empty().unwrap())
|
||||
);
|
||||
|
||||
let box3: default::Box3D<i32> = Box3D {
|
||||
min: point3(1, -10, 2),
|
||||
max: point3(6, 15, 12),
|
||||
};
|
||||
let box4 = Box3D {
|
||||
min: point3(0, -2, -5),
|
||||
max: point3(7, 10, 5),
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
box3.union(&box4),
|
||||
*box3
|
||||
.to_non_empty()
|
||||
.unwrap()
|
||||
.union(&box4.to_non_empty().unwrap())
|
||||
);
|
||||
|
||||
let rect1: default::Rect<i32> = Rect {
|
||||
origin: point2(1, 2),
|
||||
size: size2(3, 4),
|
||||
};
|
||||
let rect2 = Rect {
|
||||
origin: point2(-1, 5),
|
||||
size: size2(1, 10),
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
rect1.union(&rect2),
|
||||
*rect1
|
||||
.to_non_empty()
|
||||
.unwrap()
|
||||
.union(&rect2.to_non_empty().unwrap())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nonempty_contains() {
|
||||
use crate::default;
|
||||
use crate::{point2, point3, size2, vec2, vec3};
|
||||
|
||||
let r: NonEmpty<default::Rect<i32>> = Rect {
|
||||
origin: point2(-20, 15),
|
||||
size: size2(100, 200),
|
||||
}
|
||||
.to_non_empty()
|
||||
.unwrap();
|
||||
|
||||
assert!(r.contains_rect(&r));
|
||||
assert!(!r.contains_rect(&r.translate(vec2(1, 0))));
|
||||
assert!(!r.contains_rect(&r.translate(vec2(-1, 0))));
|
||||
assert!(!r.contains_rect(&r.translate(vec2(0, 1))));
|
||||
assert!(!r.contains_rect(&r.translate(vec2(0, -1))));
|
||||
|
||||
let b: NonEmpty<default::Box2D<i32>> = Box2D {
|
||||
min: point2(-10, 5),
|
||||
max: point2(30, 100),
|
||||
}
|
||||
.to_non_empty()
|
||||
.unwrap();
|
||||
|
||||
assert!(b.contains_box(&b));
|
||||
assert!(!b.contains_box(&b.translate(vec2(1, 0))));
|
||||
assert!(!b.contains_box(&b.translate(vec2(-1, 0))));
|
||||
assert!(!b.contains_box(&b.translate(vec2(0, 1))));
|
||||
assert!(!b.contains_box(&b.translate(vec2(0, -1))));
|
||||
|
||||
let b: NonEmpty<default::Box3D<i32>> = Box3D {
|
||||
min: point3(-1, -10, 5),
|
||||
max: point3(10, 30, 100),
|
||||
}
|
||||
.to_non_empty()
|
||||
.unwrap();
|
||||
|
||||
assert!(b.contains_box(&b));
|
||||
assert!(!b.contains_box(&b.translate(vec3(0, 1, 0))));
|
||||
assert!(!b.contains_box(&b.translate(vec3(0, -1, 0))));
|
||||
assert!(!b.contains_box(&b.translate(vec3(0, 0, 1))));
|
||||
assert!(!b.contains_box(&b.translate(vec3(0, 0, -1))));
|
||||
assert!(!b.contains_box(&b.translate(vec3(1, 1, 0))));
|
||||
assert!(!b.contains_box(&b.translate(vec3(1, -1, 0))));
|
||||
assert!(!b.contains_box(&b.translate(vec3(1, 0, 1))));
|
||||
assert!(!b.contains_box(&b.translate(vec3(1, 0, -1))));
|
||||
assert!(!b.contains_box(&b.translate(vec3(-1, 1, 0))));
|
||||
assert!(!b.contains_box(&b.translate(vec3(-1, -1, 0))));
|
||||
assert!(!b.contains_box(&b.translate(vec3(-1, 0, 1))));
|
||||
assert!(!b.contains_box(&b.translate(vec3(-1, 0, -1))));
|
||||
}
|
33
third_party/rust/euclid/src/num.rs
vendored
@ -70,12 +70,34 @@ pub trait Ceil: Copy {
|
||||
fn ceil(self) -> Self;
|
||||
}
|
||||
|
||||
macro_rules! num_int {
|
||||
($ty:ty) => {
|
||||
impl Round for $ty {
|
||||
#[inline]
|
||||
fn round(self) -> $ty {
|
||||
self
|
||||
}
|
||||
}
|
||||
impl Floor for $ty {
|
||||
#[inline]
|
||||
fn floor(self) -> $ty {
|
||||
self
|
||||
}
|
||||
}
|
||||
impl Ceil for $ty {
|
||||
#[inline]
|
||||
fn ceil(self) -> $ty {
|
||||
self
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
macro_rules! num_float {
|
||||
($ty:ty) => {
|
||||
impl Round for $ty {
|
||||
#[inline]
|
||||
fn round(self) -> $ty {
|
||||
(self + 0.5).floor()
|
||||
num_traits::Float::round(self)
|
||||
}
|
||||
}
|
||||
impl Floor for $ty {
|
||||
@ -92,5 +114,14 @@ macro_rules! num_float {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
num_int!(i16);
|
||||
num_int!(u16);
|
||||
num_int!(i32);
|
||||
num_int!(u32);
|
||||
num_int!(i64);
|
||||
num_int!(u64);
|
||||
num_int!(isize);
|
||||
num_int!(usize);
|
||||
num_float!(f32);
|
||||
num_float!(f64);
|
||||
|
192
third_party/rust/euclid/src/point.rs
vendored
@ -107,6 +107,16 @@ impl<T: fmt::Debug, U> fmt::Debug for Point2D<T, U> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: fmt::Display, U> fmt::Display for Point2D<T, U> {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(formatter, "(")?;
|
||||
fmt::Display::fmt(&self.x, formatter)?;
|
||||
write!(formatter, ",")?;
|
||||
fmt::Display::fmt(&self.y, formatter)?;
|
||||
write!(formatter, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default, U> Default for Point2D<T, U> {
|
||||
fn default() -> Self {
|
||||
Point2D::new(Default::default(), Default::default())
|
||||
@ -158,7 +168,7 @@ impl<T, U> Point2D<T, U> {
|
||||
impl<T: Copy, U> Point2D<T, U> {
|
||||
/// Create a 3d point from this one, using the specified z value.
|
||||
#[inline]
|
||||
pub fn extend(self, z: T) -> Point3D<T, U> {
|
||||
pub fn extend(&self, z: T) -> Point3D<T, U> {
|
||||
point3(self.x, self.y, z)
|
||||
}
|
||||
|
||||
@ -166,7 +176,7 @@ impl<T: Copy, U> Point2D<T, U> {
|
||||
///
|
||||
/// Equivalent to subtracting the origin from this point.
|
||||
#[inline]
|
||||
pub fn to_vector(self) -> Vector2D<T, U> {
|
||||
pub fn to_vector(&self) -> Vector2D<T, U> {
|
||||
Vector2D {
|
||||
x: self.x,
|
||||
y: self.y,
|
||||
@ -187,7 +197,7 @@ impl<T: Copy, U> Point2D<T, U> {
|
||||
/// assert_eq!(point.yx(), point2(-8, 1));
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn yx(self) -> Self {
|
||||
pub fn yx(&self) -> Self {
|
||||
point2(self.y, self.x)
|
||||
}
|
||||
|
||||
@ -205,7 +215,7 @@ impl<T: Copy, U> Point2D<T, U> {
|
||||
/// assert_eq!(point.y, point.to_untyped().y);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn to_untyped(self) -> Point2D<T, UnknownUnit> {
|
||||
pub fn to_untyped(&self) -> Point2D<T, UnknownUnit> {
|
||||
point2(self.x, self.y)
|
||||
}
|
||||
|
||||
@ -224,7 +234,7 @@ impl<T: Copy, U> Point2D<T, U> {
|
||||
/// assert_eq!(point.y, point.cast_unit::<Cm>().y);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn cast_unit<V>(self) -> Point2D<T, V> {
|
||||
pub fn cast_unit<V>(&self) -> Point2D<T, V> {
|
||||
point2(self.x, self.y)
|
||||
}
|
||||
|
||||
@ -241,7 +251,7 @@ impl<T: Copy, U> Point2D<T, U> {
|
||||
/// assert_eq!(point.to_array(), [1, -8]);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn to_array(self) -> [T; 2] {
|
||||
pub fn to_array(&self) -> [T; 2] {
|
||||
[self.x, self.y]
|
||||
}
|
||||
|
||||
@ -258,13 +268,13 @@ impl<T: Copy, U> Point2D<T, U> {
|
||||
/// assert_eq!(point.to_tuple(), (1, -8));
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn to_tuple(self) -> (T, T) {
|
||||
pub fn to_tuple(&self) -> (T, T) {
|
||||
(self.x, self.y)
|
||||
}
|
||||
|
||||
/// Convert into a 3d point with z-coordinate equals to zero.
|
||||
#[inline]
|
||||
pub fn to_3d(self) -> Point3D<T, U>
|
||||
pub fn to_3d(&self) -> Point3D<T, U>
|
||||
where
|
||||
T: Zero,
|
||||
{
|
||||
@ -283,7 +293,7 @@ impl<T: Copy, U> Point2D<T, U> {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn round(self) -> Self
|
||||
pub fn round(&self) -> Self
|
||||
where
|
||||
T: Round,
|
||||
{
|
||||
@ -302,7 +312,7 @@ impl<T: Copy, U> Point2D<T, U> {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn ceil(self) -> Self
|
||||
pub fn ceil(&self) -> Self
|
||||
where
|
||||
T: Ceil,
|
||||
{
|
||||
@ -321,7 +331,7 @@ impl<T: Copy, U> Point2D<T, U> {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn floor(self) -> Self
|
||||
pub fn floor(&self) -> Self
|
||||
where
|
||||
T: Floor,
|
||||
{
|
||||
@ -346,7 +356,7 @@ impl<T: Copy, U> Point2D<T, U> {
|
||||
/// assert_eq!(from.lerp(to, 2.0), point2(16.0, -18.0));
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn lerp(self, other: Self, t: T) -> Self
|
||||
pub fn lerp(&self, other: Self, t: T) -> Self
|
||||
where
|
||||
T: One + Sub<Output = T> + Mul<Output = T> + Add<Output = T>,
|
||||
{
|
||||
@ -371,7 +381,7 @@ impl<T: PartialOrd, U> Point2D<T, U> {
|
||||
///
|
||||
/// Shortcut for `self.max(start).min(end)`.
|
||||
#[inline]
|
||||
pub fn clamp(self, start: Self, end: Self) -> Self
|
||||
pub fn clamp(&self, start: Self, end: Self) -> Self
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
@ -386,7 +396,7 @@ impl<T: NumCast + Copy, U> Point2D<T, U> {
|
||||
/// as one would expect from a simple cast, but this behavior does not always make sense
|
||||
/// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
|
||||
#[inline]
|
||||
pub fn cast<NewT: NumCast>(self) -> Point2D<NewT, U> {
|
||||
pub fn cast<NewT: NumCast>(&self) -> Point2D<NewT, U> {
|
||||
self.try_cast().unwrap()
|
||||
}
|
||||
|
||||
@ -395,7 +405,7 @@ impl<T: NumCast + Copy, U> Point2D<T, U> {
|
||||
/// When casting from floating point to integer coordinates, the decimals are truncated
|
||||
/// as one would expect from a simple cast, but this behavior does not always make sense
|
||||
/// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
|
||||
pub fn try_cast<NewT: NumCast>(self) -> Option<Point2D<NewT, U>> {
|
||||
pub fn try_cast<NewT: NumCast>(&self) -> Option<Point2D<NewT, U>> {
|
||||
match (NumCast::from(self.x), NumCast::from(self.y)) {
|
||||
(Some(x), Some(y)) => Some(point2(x, y)),
|
||||
_ => None,
|
||||
@ -406,13 +416,13 @@ impl<T: NumCast + Copy, U> Point2D<T, U> {
|
||||
|
||||
/// Cast into an `f32` point.
|
||||
#[inline]
|
||||
pub fn to_f32(self) -> Point2D<f32, U> {
|
||||
pub fn to_f32(&self) -> Point2D<f32, U> {
|
||||
self.cast()
|
||||
}
|
||||
|
||||
/// Cast into an `f64` point.
|
||||
#[inline]
|
||||
pub fn to_f64(self) -> Point2D<f64, U> {
|
||||
pub fn to_f64(&self) -> Point2D<f64, U> {
|
||||
self.cast()
|
||||
}
|
||||
|
||||
@ -422,7 +432,7 @@ impl<T: NumCast + Copy, U> Point2D<T, U> {
|
||||
/// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
|
||||
/// the desired conversion behavior.
|
||||
#[inline]
|
||||
pub fn to_usize(self) -> Point2D<usize, U> {
|
||||
pub fn to_usize(&self) -> Point2D<usize, U> {
|
||||
self.cast()
|
||||
}
|
||||
|
||||
@ -432,7 +442,7 @@ impl<T: NumCast + Copy, U> Point2D<T, U> {
|
||||
/// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
|
||||
/// the desired conversion behavior.
|
||||
#[inline]
|
||||
pub fn to_u32(self) -> Point2D<u32, U> {
|
||||
pub fn to_u32(&self) -> Point2D<u32, U> {
|
||||
self.cast()
|
||||
}
|
||||
|
||||
@ -442,7 +452,7 @@ impl<T: NumCast + Copy, U> Point2D<T, U> {
|
||||
/// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
|
||||
/// the desired conversion behavior.
|
||||
#[inline]
|
||||
pub fn to_i32(self) -> Point2D<i32, U> {
|
||||
pub fn to_i32(&self) -> Point2D<i32, U> {
|
||||
self.cast()
|
||||
}
|
||||
|
||||
@ -452,14 +462,14 @@ impl<T: NumCast + Copy, U> Point2D<T, U> {
|
||||
/// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
|
||||
/// the desired conversion behavior.
|
||||
#[inline]
|
||||
pub fn to_i64(self) -> Point2D<i64, U> {
|
||||
pub fn to_i64(&self) -> Point2D<i64, U> {
|
||||
self.cast()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Add<T, Output = T>, U> Point2D<T, U> {
|
||||
#[inline]
|
||||
pub fn add_size(self, other: &Size2D<T, U>) -> Self {
|
||||
pub fn add_size(&self, other: &Size2D<T, U>) -> Self {
|
||||
point2(self.x + other.width, self.y + other.height)
|
||||
}
|
||||
}
|
||||
@ -555,12 +565,12 @@ impl<T: Copy + Sub<T, Output = T>, U> SubAssign<Vector2D<T, U>> for Point2D<T, U
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Mul, U> Mul<T> for Point2D<T, U> {
|
||||
impl<T: Clone + Mul, U> Mul<T> for Point2D<T, U> {
|
||||
type Output = Point2D<T::Output, U>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, scale: T) -> Self::Output {
|
||||
point2(self.x * scale, self.y * scale)
|
||||
point2(self.x * scale.clone(), self.y * scale)
|
||||
}
|
||||
}
|
||||
|
||||
@ -571,29 +581,29 @@ impl<T: Copy + Mul<T, Output = T>, U> MulAssign<T> for Point2D<T, U> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Point2D<T, U1> {
|
||||
impl<T: Clone + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Point2D<T, U1> {
|
||||
type Output = Point2D<T::Output, U2>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, scale: Scale<T, U1, U2>) -> Self::Output {
|
||||
point2(self.x * scale.0, self.y * scale.0)
|
||||
point2(self.x * scale.0.clone(), self.y * scale.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + MulAssign, U> MulAssign<Scale<T, U, U>> for Point2D<T, U> {
|
||||
impl<T: Clone + MulAssign, U> MulAssign<Scale<T, U, U>> for Point2D<T, U> {
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, scale: Scale<T, U, U>) {
|
||||
self.x *= scale.0;
|
||||
self.x *= scale.0.clone();
|
||||
self.y *= scale.0;
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Div, U> Div<T> for Point2D<T, U> {
|
||||
impl<T: Clone + Div, U> Div<T> for Point2D<T, U> {
|
||||
type Output = Point2D<T::Output, U>;
|
||||
|
||||
#[inline]
|
||||
fn div(self, scale: T) -> Self::Output {
|
||||
point2(self.x / scale, self.y / scale)
|
||||
point2(self.x / scale.clone(), self.y / scale)
|
||||
}
|
||||
}
|
||||
|
||||
@ -604,19 +614,19 @@ impl<T: Copy + Div<T, Output = T>, U> DivAssign<T> for Point2D<T, U> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Div, U1, U2> Div<Scale<T, U1, U2>> for Point2D<T, U2> {
|
||||
impl<T: Clone + Div, U1, U2> Div<Scale<T, U1, U2>> for Point2D<T, U2> {
|
||||
type Output = Point2D<T::Output, U1>;
|
||||
|
||||
#[inline]
|
||||
fn div(self, scale: Scale<T, U1, U2>) -> Self::Output {
|
||||
point2(self.x / scale.0, self.y / scale.0)
|
||||
point2(self.x / scale.0.clone(), self.y / scale.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + DivAssign, U> DivAssign<Scale<T, U, U>> for Point2D<T, U> {
|
||||
impl<T: Clone + DivAssign, U> DivAssign<Scale<T, U, U>> for Point2D<T, U> {
|
||||
#[inline]
|
||||
fn div_assign(&mut self, scale: Scale<T, U, U>) {
|
||||
self.x /= scale.0;
|
||||
self.x /= scale.0.clone();
|
||||
self.y /= scale.0;
|
||||
}
|
||||
}
|
||||
@ -632,7 +642,7 @@ impl<T: Round, U> Round for Point2D<T, U> {
|
||||
/// See [Point2D::round()](#method.round)
|
||||
#[inline]
|
||||
fn round(self) -> Self {
|
||||
self.round()
|
||||
(&self).round()
|
||||
}
|
||||
}
|
||||
|
||||
@ -640,7 +650,7 @@ impl<T: Ceil, U> Ceil for Point2D<T, U> {
|
||||
/// See [Point2D::ceil()](#method.ceil)
|
||||
#[inline]
|
||||
fn ceil(self) -> Self {
|
||||
self.ceil()
|
||||
(&self).ceil()
|
||||
}
|
||||
}
|
||||
|
||||
@ -648,7 +658,7 @@ impl<T: Floor, U> Floor for Point2D<T, U> {
|
||||
/// See [Point2D::floor()](#method.floor)
|
||||
#[inline]
|
||||
fn floor(self) -> Self {
|
||||
self.floor()
|
||||
(&self).floor()
|
||||
}
|
||||
}
|
||||
|
||||
@ -777,6 +787,18 @@ impl<T: fmt::Debug, U> fmt::Debug for Point3D<T, U> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: fmt::Display, U> fmt::Display for Point3D<T, U> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "(")?;
|
||||
fmt::Display::fmt(&self.x, f)?;
|
||||
write!(f, ",")?;
|
||||
fmt::Display::fmt(&self.y, f)?;
|
||||
write!(f, ",")?;
|
||||
fmt::Display::fmt(&self.z, f)?;
|
||||
write!(f, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default, U> Default for Point3D<T, U> {
|
||||
fn default() -> Self {
|
||||
Point3D::new(Default::default(), Default::default(), Default::default())
|
||||
@ -831,7 +853,7 @@ impl<T: Copy, U> Point3D<T, U> {
|
||||
///
|
||||
/// Equivalent to subtracting the origin to this point.
|
||||
#[inline]
|
||||
pub fn to_vector(self) -> Vector3D<T, U> {
|
||||
pub fn to_vector(&self) -> Vector3D<T, U> {
|
||||
Vector3D {
|
||||
x: self.x,
|
||||
y: self.y,
|
||||
@ -842,19 +864,19 @@ impl<T: Copy, U> Point3D<T, U> {
|
||||
|
||||
/// Returns a 2d point using this point's x and y coordinates
|
||||
#[inline]
|
||||
pub fn xy(self) -> Point2D<T, U> {
|
||||
pub fn xy(&self) -> Point2D<T, U> {
|
||||
point2(self.x, self.y)
|
||||
}
|
||||
|
||||
/// Returns a 2d point using this point's x and z coordinates
|
||||
#[inline]
|
||||
pub fn xz(self) -> Point2D<T, U> {
|
||||
pub fn xz(&self) -> Point2D<T, U> {
|
||||
point2(self.x, self.z)
|
||||
}
|
||||
|
||||
/// Returns a 2d point using this point's x and z coordinates
|
||||
#[inline]
|
||||
pub fn yz(self) -> Point2D<T, U> {
|
||||
pub fn yz(&self) -> Point2D<T, U> {
|
||||
point2(self.y, self.z)
|
||||
}
|
||||
|
||||
@ -871,12 +893,12 @@ impl<T: Copy, U> Point3D<T, U> {
|
||||
/// assert_eq!(point.to_array(), [1, -8, 0]);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn to_array(self) -> [T; 3] {
|
||||
pub fn to_array(&self) -> [T; 3] {
|
||||
[self.x, self.y, self.z]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_array_4d(self) -> [T; 4]
|
||||
pub fn to_array_4d(&self) -> [T; 4]
|
||||
where
|
||||
T: One,
|
||||
{
|
||||
@ -896,12 +918,12 @@ impl<T: Copy, U> Point3D<T, U> {
|
||||
/// assert_eq!(point.to_tuple(), (1, -8, 0));
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn to_tuple(self) -> (T, T, T) {
|
||||
pub fn to_tuple(&self) -> (T, T, T) {
|
||||
(self.x, self.y, self.z)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_tuple_4d(self) -> (T, T, T, T)
|
||||
pub fn to_tuple_4d(&self) -> (T, T, T, T)
|
||||
where
|
||||
T: One,
|
||||
{
|
||||
@ -923,7 +945,7 @@ impl<T: Copy, U> Point3D<T, U> {
|
||||
/// assert_eq!(point.z, point.to_untyped().z);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn to_untyped(self) -> Point3D<T, UnknownUnit> {
|
||||
pub fn to_untyped(&self) -> Point3D<T, UnknownUnit> {
|
||||
point3(self.x, self.y, self.z)
|
||||
}
|
||||
|
||||
@ -943,13 +965,13 @@ impl<T: Copy, U> Point3D<T, U> {
|
||||
/// assert_eq!(point.z, point.cast_unit::<Cm>().z);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn cast_unit<V>(self) -> Point3D<T, V> {
|
||||
pub fn cast_unit<V>(&self) -> Point3D<T, V> {
|
||||
point3(self.x, self.y, self.z)
|
||||
}
|
||||
|
||||
/// Convert into a 2d point.
|
||||
#[inline]
|
||||
pub fn to_2d(self) -> Point2D<T, U> {
|
||||
pub fn to_2d(&self) -> Point2D<T, U> {
|
||||
self.xy()
|
||||
}
|
||||
|
||||
@ -965,7 +987,7 @@ impl<T: Copy, U> Point3D<T, U> {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn round(self) -> Self
|
||||
pub fn round(&self) -> Self
|
||||
where
|
||||
T: Round,
|
||||
{
|
||||
@ -984,7 +1006,7 @@ impl<T: Copy, U> Point3D<T, U> {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn ceil(self) -> Self
|
||||
pub fn ceil(&self) -> Self
|
||||
where
|
||||
T: Ceil,
|
||||
{
|
||||
@ -1003,7 +1025,7 @@ impl<T: Copy, U> Point3D<T, U> {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn floor(self) -> Self
|
||||
pub fn floor(&self) -> Self
|
||||
where
|
||||
T: Floor,
|
||||
{
|
||||
@ -1028,7 +1050,7 @@ impl<T: Copy, U> Point3D<T, U> {
|
||||
/// assert_eq!(from.lerp(to, 2.0), point3(16.0, -18.0, 1.0));
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn lerp(self, other: Self, t: T) -> Self
|
||||
pub fn lerp(&self, other: Self, t: T) -> Self
|
||||
where
|
||||
T: One + Sub<Output = T> + Mul<Output = T> + Add<Output = T>,
|
||||
{
|
||||
@ -1065,7 +1087,7 @@ impl<T: PartialOrd, U> Point3D<T, U> {
|
||||
///
|
||||
/// Shortcut for `self.max(start).min(end)`.
|
||||
#[inline]
|
||||
pub fn clamp(self, start: Self, end: Self) -> Self
|
||||
pub fn clamp(&self, start: Self, end: Self) -> Self
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
@ -1080,7 +1102,7 @@ impl<T: NumCast + Copy, U> Point3D<T, U> {
|
||||
/// as one would expect from a simple cast, but this behavior does not always make sense
|
||||
/// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
|
||||
#[inline]
|
||||
pub fn cast<NewT: NumCast>(self) -> Point3D<NewT, U> {
|
||||
pub fn cast<NewT: NumCast>(&self) -> Point3D<NewT, U> {
|
||||
self.try_cast().unwrap()
|
||||
}
|
||||
|
||||
@ -1089,7 +1111,7 @@ impl<T: NumCast + Copy, U> Point3D<T, U> {
|
||||
/// When casting from floating point to integer coordinates, the decimals are truncated
|
||||
/// as one would expect from a simple cast, but this behavior does not always make sense
|
||||
/// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
|
||||
pub fn try_cast<NewT: NumCast>(self) -> Option<Point3D<NewT, U>> {
|
||||
pub fn try_cast<NewT: NumCast>(&self) -> Option<Point3D<NewT, U>> {
|
||||
match (
|
||||
NumCast::from(self.x),
|
||||
NumCast::from(self.y),
|
||||
@ -1104,13 +1126,13 @@ impl<T: NumCast + Copy, U> Point3D<T, U> {
|
||||
|
||||
/// Cast into an `f32` point.
|
||||
#[inline]
|
||||
pub fn to_f32(self) -> Point3D<f32, U> {
|
||||
pub fn to_f32(&self) -> Point3D<f32, U> {
|
||||
self.cast()
|
||||
}
|
||||
|
||||
/// Cast into an `f64` point.
|
||||
#[inline]
|
||||
pub fn to_f64(self) -> Point3D<f64, U> {
|
||||
pub fn to_f64(&self) -> Point3D<f64, U> {
|
||||
self.cast()
|
||||
}
|
||||
|
||||
@ -1120,7 +1142,7 @@ impl<T: NumCast + Copy, U> Point3D<T, U> {
|
||||
/// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
|
||||
/// the desired conversion behavior.
|
||||
#[inline]
|
||||
pub fn to_usize(self) -> Point3D<usize, U> {
|
||||
pub fn to_usize(&self) -> Point3D<usize, U> {
|
||||
self.cast()
|
||||
}
|
||||
|
||||
@ -1130,7 +1152,7 @@ impl<T: NumCast + Copy, U> Point3D<T, U> {
|
||||
/// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
|
||||
/// the desired conversion behavior.
|
||||
#[inline]
|
||||
pub fn to_u32(self) -> Point3D<u32, U> {
|
||||
pub fn to_u32(&self) -> Point3D<u32, U> {
|
||||
self.cast()
|
||||
}
|
||||
|
||||
@ -1140,7 +1162,7 @@ impl<T: NumCast + Copy, U> Point3D<T, U> {
|
||||
/// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
|
||||
/// the desired conversion behavior.
|
||||
#[inline]
|
||||
pub fn to_i32(self) -> Point3D<i32, U> {
|
||||
pub fn to_i32(&self) -> Point3D<i32, U> {
|
||||
self.cast()
|
||||
}
|
||||
|
||||
@ -1150,14 +1172,14 @@ impl<T: NumCast + Copy, U> Point3D<T, U> {
|
||||
/// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
|
||||
/// the desired conversion behavior.
|
||||
#[inline]
|
||||
pub fn to_i64(self) -> Point3D<i64, U> {
|
||||
pub fn to_i64(&self) -> Point3D<i64, U> {
|
||||
self.cast()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Add<T, Output = T>, U> Point3D<T, U> {
|
||||
#[inline]
|
||||
pub fn add_size(self, other: Size3D<T, U>) -> Self {
|
||||
pub fn add_size(&self, other: &Size3D<T, U>) -> Self {
|
||||
point3(
|
||||
self.x + other.width,
|
||||
self.y + other.height,
|
||||
@ -1267,84 +1289,84 @@ impl<T: Copy + Sub<T, Output = T>, U> SubAssign<Vector3D<T, U>> for Point3D<T, U
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Mul, U> Mul<T> for Point3D<T, U> {
|
||||
impl<T: Clone + Mul, U> Mul<T> for Point3D<T, U> {
|
||||
type Output = Point3D<T::Output, U>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, scale: T) -> Self::Output {
|
||||
point3(
|
||||
self.x * scale,
|
||||
self.y * scale,
|
||||
self.x * scale.clone(),
|
||||
self.y * scale.clone(),
|
||||
self.z * scale,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + MulAssign, U> MulAssign<T> for Point3D<T, U> {
|
||||
impl<T: Clone + MulAssign, U> MulAssign<T> for Point3D<T, U> {
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, scale: T) {
|
||||
self.x *= scale;
|
||||
self.y *= scale;
|
||||
self.x *= scale.clone();
|
||||
self.y *= scale.clone();
|
||||
self.z *= scale;
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Point3D<T, U1> {
|
||||
impl<T: Clone + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Point3D<T, U1> {
|
||||
type Output = Point3D<T::Output, U2>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, scale: Scale<T, U1, U2>) -> Self::Output {
|
||||
point3(
|
||||
self.x * scale.0,
|
||||
self.y * scale.0,
|
||||
self.x * scale.0.clone(),
|
||||
self.y * scale.0.clone(),
|
||||
self.z * scale.0,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + MulAssign, U> MulAssign<Scale<T, U, U>> for Point3D<T, U> {
|
||||
impl<T: Clone + MulAssign, U> MulAssign<Scale<T, U, U>> for Point3D<T, U> {
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, scale: Scale<T, U, U>) {
|
||||
*self *= scale.0;
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Div, U> Div<T> for Point3D<T, U> {
|
||||
impl<T: Clone + Div, U> Div<T> for Point3D<T, U> {
|
||||
type Output = Point3D<T::Output, U>;
|
||||
|
||||
#[inline]
|
||||
fn div(self, scale: T) -> Self::Output {
|
||||
point3(
|
||||
self.x / scale,
|
||||
self.y / scale,
|
||||
self.x / scale.clone(),
|
||||
self.y / scale.clone(),
|
||||
self.z / scale,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + DivAssign, U> DivAssign<T> for Point3D<T, U> {
|
||||
impl<T: Clone + DivAssign, U> DivAssign<T> for Point3D<T, U> {
|
||||
#[inline]
|
||||
fn div_assign(&mut self, scale: T) {
|
||||
self.x /= scale;
|
||||
self.y /= scale;
|
||||
self.x /= scale.clone();
|
||||
self.y /= scale.clone();
|
||||
self.z /= scale;
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Div, U1, U2> Div<Scale<T, U1, U2>> for Point3D<T, U2> {
|
||||
impl<T: Clone + Div, U1, U2> Div<Scale<T, U1, U2>> for Point3D<T, U2> {
|
||||
type Output = Point3D<T::Output, U1>;
|
||||
|
||||
#[inline]
|
||||
fn div(self, scale: Scale<T, U1, U2>) -> Self::Output {
|
||||
point3(
|
||||
self.x / scale.0,
|
||||
self.y / scale.0,
|
||||
self.x / scale.0.clone(),
|
||||
self.y / scale.0.clone(),
|
||||
self.z / scale.0,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + DivAssign, U> DivAssign<Scale<T, U, U>> for Point3D<T, U> {
|
||||
impl<T: Clone + DivAssign, U> DivAssign<Scale<T, U, U>> for Point3D<T, U> {
|
||||
#[inline]
|
||||
fn div_assign(&mut self, scale: Scale<T, U, U>) {
|
||||
*self /= scale.0;
|
||||
@ -1362,7 +1384,7 @@ impl<T: Round, U> Round for Point3D<T, U> {
|
||||
/// See [Point3D::round()](#method.round)
|
||||
#[inline]
|
||||
fn round(self) -> Self {
|
||||
self.round()
|
||||
(&self).round()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1370,7 +1392,7 @@ impl<T: Ceil, U> Ceil for Point3D<T, U> {
|
||||
/// See [Point3D::ceil()](#method.ceil)
|
||||
#[inline]
|
||||
fn ceil(self) -> Self {
|
||||
self.ceil()
|
||||
(&self).ceil()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1378,7 +1400,7 @@ impl<T: Floor, U> Floor for Point3D<T, U> {
|
||||
/// See [Point3D::floor()](#method.floor)
|
||||
#[inline]
|
||||
fn floor(self) -> Self {
|
||||
self.floor()
|
||||
(&self).floor()
|
||||
}
|
||||
}
|
||||
|
||||
|
71
third_party/rust/euclid/src/rect.rs
vendored
@ -9,6 +9,7 @@
|
||||
|
||||
use super::UnknownUnit;
|
||||
use crate::box2d::Box2D;
|
||||
use crate::nonempty::NonEmpty;
|
||||
use crate::num::*;
|
||||
use crate::point::Point2D;
|
||||
use crate::scale::Scale;
|
||||
@ -27,22 +28,6 @@ use core::hash::{Hash, Hasher};
|
||||
use core::ops::{Add, Div, DivAssign, Mul, MulAssign, Range, Sub};
|
||||
|
||||
/// A 2d Rectangle optionally tagged with a unit.
|
||||
///
|
||||
/// # Representation
|
||||
///
|
||||
/// `Rect` is represented by an origin point and a size.
|
||||
///
|
||||
/// See [`Rect`] for a rectangle represented by two endpoints.
|
||||
///
|
||||
/// # Empty rectangle
|
||||
///
|
||||
/// A rectangle is considered empty (see [`is_empty`]) if any of the following is true:
|
||||
/// - it's area is empty,
|
||||
/// - it's area is negative (`size.x < 0` or `size.y < 0`),
|
||||
/// - it contains NaNs.
|
||||
///
|
||||
/// [`is_empty`]: #method.is_empty
|
||||
/// [`Box2D`]: struct.Box2D.html
|
||||
#[repr(C)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(
|
||||
@ -87,6 +72,16 @@ impl<T: fmt::Debug, U> fmt::Debug for Rect<T, U> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: fmt::Display, U> fmt::Display for Rect<T, U> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Rect(")?;
|
||||
fmt::Display::fmt(&self.size, f)?;
|
||||
write!(f, " at ")?;
|
||||
fmt::Display::fmt(&self.origin, f)?;
|
||||
write!(f, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default, U> Default for Rect<T, U> {
|
||||
fn default() -> Self {
|
||||
Rect::new(Default::default(), Default::default())
|
||||
@ -215,9 +210,8 @@ where
|
||||
{
|
||||
#[inline]
|
||||
pub fn intersection(&self, other: &Self) -> Option<Self> {
|
||||
let box2d = self.to_box2d().intersection_unchecked(&other.to_box2d());
|
||||
|
||||
if box2d.is_empty() {
|
||||
let box2d = self.to_box2d().intersection(&other.to_box2d());
|
||||
if box2d.is_empty_or_negative() {
|
||||
return None;
|
||||
}
|
||||
|
||||
@ -251,7 +245,7 @@ where
|
||||
/// nonempty but this rectangle is empty.
|
||||
#[inline]
|
||||
pub fn contains_rect(&self, rect: &Self) -> bool {
|
||||
rect.is_empty()
|
||||
rect.is_empty_or_negative()
|
||||
|| (self.min_x() <= rect.min_x()
|
||||
&& rect.max_x() <= self.max_x()
|
||||
&& self.min_y() <= rect.min_y()
|
||||
@ -384,41 +378,48 @@ impl<T: Copy + Mul<T, Output = T>, U> Rect<T, U> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Zero + PartialOrd, U> Rect<T, U> {
|
||||
#[inline]
|
||||
impl<T: Zero + PartialEq, U> Rect<T, U> {
|
||||
/// Returns true if the size is zero, regardless of the origin's value.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.size.is_empty()
|
||||
self.size.width == Zero::zero() || self.size.height == Zero::zero()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Zero + PartialOrd, U> Rect<T, U> {
|
||||
#[inline]
|
||||
pub fn is_empty_or_negative(&self) -> bool {
|
||||
self.size.is_empty_or_negative()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Zero + PartialOrd, U> Rect<T, U> {
|
||||
#[inline]
|
||||
pub fn to_non_empty(&self) -> Option<Self> {
|
||||
if self.is_empty() {
|
||||
pub fn to_non_empty(&self) -> Option<NonEmpty<Self>> {
|
||||
if self.is_empty_or_negative() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(*self)
|
||||
Some(NonEmpty(*self))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Mul, U> Mul<T> for Rect<T, U> {
|
||||
impl<T: Clone + Mul, U> Mul<T> for Rect<T, U> {
|
||||
type Output = Rect<T::Output, U>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, scale: T) -> Self::Output {
|
||||
Rect::new(self.origin * scale, self.size * scale)
|
||||
Rect::new(self.origin * scale.clone(), self.size * scale)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + MulAssign, U> MulAssign<T> for Rect<T, U> {
|
||||
impl<T: Clone + MulAssign, U> MulAssign<T> for Rect<T, U> {
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, scale: T) {
|
||||
*self *= Scale::new(scale);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Div, U> Div<T> for Rect<T, U> {
|
||||
impl<T: Clone + Div, U> Div<T> for Rect<T, U> {
|
||||
type Output = Rect<T::Output, U>;
|
||||
|
||||
#[inline]
|
||||
@ -427,14 +428,14 @@ impl<T: Copy + Div, U> Div<T> for Rect<T, U> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + DivAssign, U> DivAssign<T> for Rect<T, U> {
|
||||
impl<T: Clone + DivAssign, U> DivAssign<T> for Rect<T, U> {
|
||||
#[inline]
|
||||
fn div_assign(&mut self, scale: T) {
|
||||
*self /= Scale::new(scale);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Rect<T, U1> {
|
||||
impl<T: Clone + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Rect<T, U1> {
|
||||
type Output = Rect<T::Output, U2>;
|
||||
|
||||
#[inline]
|
||||
@ -443,7 +444,7 @@ impl<T: Copy + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Rect<T, U1> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + MulAssign, U> MulAssign<Scale<T, U, U>> for Rect<T, U> {
|
||||
impl<T: Clone + MulAssign, U> MulAssign<Scale<T, U, U>> for Rect<T, U> {
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, scale: Scale<T, U, U>) {
|
||||
self.origin *= scale.clone();
|
||||
@ -451,7 +452,7 @@ impl<T: Copy + MulAssign, U> MulAssign<Scale<T, U, U>> for Rect<T, U> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Div, U1, U2> Div<Scale<T, U1, U2>> for Rect<T, U2> {
|
||||
impl<T: Clone + Div, U1, U2> Div<Scale<T, U1, U2>> for Rect<T, U2> {
|
||||
type Output = Rect<T::Output, U1>;
|
||||
|
||||
#[inline]
|
||||
@ -460,7 +461,7 @@ impl<T: Copy + Div, U1, U2> Div<Scale<T, U1, U2>> for Rect<T, U2> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + DivAssign, U> DivAssign<Scale<T, U, U>> for Rect<T, U> {
|
||||
impl<T: Clone + DivAssign, U> DivAssign<Scale<T, U, U>> for Rect<T, U> {
|
||||
#[inline]
|
||||
fn div_assign(&mut self, scale: Scale<T, U, U>) {
|
||||
self.origin /= scale.clone();
|
||||
|
42
third_party/rust/euclid/src/rigid.rs
vendored
@ -114,7 +114,7 @@ impl<T: Float + ApproxEq<T>, Src, Dst> RigidTransform3D<T, Src, Dst> {
|
||||
///
|
||||
/// i.e., this produces `self * other` in row-vector notation
|
||||
#[inline]
|
||||
pub fn then<Dst2>(
|
||||
pub fn post_transform<Dst2>(
|
||||
&self,
|
||||
other: &RigidTransform3D<T, Dst, Dst2>,
|
||||
) -> RigidTransform3D<T, Src, Dst2> {
|
||||
@ -131,7 +131,7 @@ impl<T: Float + ApproxEq<T>, Src, Dst> RigidTransform3D<T, Src, Dst> {
|
||||
// T' * T2 = T'' = vector addition of translations T2 and T'
|
||||
|
||||
let t_prime = other.rotation.transform_vector3d(self.translation);
|
||||
let r_prime = self.rotation.then(&other.rotation);
|
||||
let r_prime = self.rotation.post_rotate(&other.rotation);
|
||||
let t_prime2 = t_prime + other.translation;
|
||||
RigidTransform3D {
|
||||
rotation: r_prime,
|
||||
@ -139,6 +139,18 @@ impl<T: Float + ApproxEq<T>, Src, Dst> RigidTransform3D<T, Src, Dst> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the multiplication of the two transforms such that
|
||||
/// self's transformation applies after other's transformation.
|
||||
///
|
||||
/// i.e., this produces `other * self` in row-vector notation
|
||||
#[inline]
|
||||
pub fn pre_transform<Src2>(
|
||||
&self,
|
||||
other: &RigidTransform3D<T, Src2, Src>,
|
||||
) -> RigidTransform3D<T, Src2, Dst> {
|
||||
other.post_transform(&self)
|
||||
}
|
||||
|
||||
/// Inverts the transformation
|
||||
#[inline]
|
||||
pub fn inverse(&self) -> RigidTransform3D<T, Dst, Src> {
|
||||
@ -161,7 +173,9 @@ impl<T: Float + ApproxEq<T>, Src, Dst> RigidTransform3D<T, Src, Dst> {
|
||||
where
|
||||
T: Trig,
|
||||
{
|
||||
self.rotation.to_transform().then(&self.translation.to_transform())
|
||||
self.translation
|
||||
.to_transform()
|
||||
.pre_transform(&self.rotation.to_transform())
|
||||
}
|
||||
|
||||
/// Drop the units, preserving only the numeric value.
|
||||
@ -209,12 +223,16 @@ mod test {
|
||||
|
||||
let rigid = RigidTransform3D::new(rotation, translation);
|
||||
assert!(rigid.to_transform().approx_eq(
|
||||
&rotation.to_transform().then(&translation.to_transform())
|
||||
&translation
|
||||
.to_transform()
|
||||
.pre_transform(&rotation.to_transform())
|
||||
));
|
||||
|
||||
let rigid = RigidTransform3D::new_from_reversed(translation, rotation);
|
||||
assert!(rigid.to_transform().approx_eq(
|
||||
&translation.to_transform().then(&rotation.to_transform())
|
||||
&translation
|
||||
.to_transform()
|
||||
.post_transform(&rotation.to_transform())
|
||||
));
|
||||
}
|
||||
|
||||
@ -227,7 +245,7 @@ mod test {
|
||||
let (t2, r2) = rigid.decompose_reversed();
|
||||
assert!(rigid
|
||||
.to_transform()
|
||||
.approx_eq(&t2.to_transform().then(&r2.to_transform())));
|
||||
.approx_eq(&t2.to_transform().post_transform(&r2.to_transform())));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -238,7 +256,7 @@ mod test {
|
||||
let rigid = RigidTransform3D::new(rotation, translation);
|
||||
let inverse = rigid.inverse();
|
||||
assert!(rigid
|
||||
.then(&inverse)
|
||||
.post_transform(&inverse)
|
||||
.to_transform()
|
||||
.approx_eq(&Transform3D::identity()));
|
||||
assert!(inverse
|
||||
@ -256,12 +274,12 @@ mod test {
|
||||
let rigid2 = RigidTransform3D::new(rotation2, translation2);
|
||||
|
||||
assert!(rigid
|
||||
.then(&rigid2)
|
||||
.post_transform(&rigid2)
|
||||
.to_transform()
|
||||
.approx_eq(&rigid.to_transform().then(&rigid2.to_transform())));
|
||||
assert!(rigid2
|
||||
.then(&rigid)
|
||||
.approx_eq(&rigid.to_transform().post_transform(&rigid2.to_transform())));
|
||||
assert!(rigid
|
||||
.pre_transform(&rigid2)
|
||||
.to_transform()
|
||||
.approx_eq(&rigid2.to_transform().then(&rigid.to_transform())));
|
||||
.approx_eq(&rigid.to_transform().pre_transform(&rigid2.to_transform())));
|
||||
}
|
||||
}
|
||||
|
73
third_party/rust/euclid/src/rotation.rs
vendored
@ -158,11 +158,11 @@ impl<T: Copy, Src, Dst> Rotation2D<T, Src, Dst> {
|
||||
|
||||
impl<T, Src, Dst> Rotation2D<T, Src, Dst>
|
||||
where
|
||||
T: Copy,
|
||||
T: Clone,
|
||||
{
|
||||
/// Returns self.angle as a strongly typed `Angle<T>`.
|
||||
pub fn get_angle(&self) -> Angle<T> {
|
||||
Angle::radians(self.angle)
|
||||
Angle::radians(self.angle.clone())
|
||||
}
|
||||
}
|
||||
|
||||
@ -181,13 +181,22 @@ impl<T: Float, Src, Dst> Rotation2D<T, Src, Dst> {
|
||||
|
||||
/// Returns a rotation representing the other rotation followed by this rotation.
|
||||
#[inline]
|
||||
pub fn then<NewSrc>(
|
||||
pub fn pre_rotate<NewSrc>(
|
||||
&self,
|
||||
other: &Rotation2D<T, NewSrc, Src>,
|
||||
) -> Rotation2D<T, NewSrc, Dst> {
|
||||
Rotation2D::radians(self.angle + other.angle)
|
||||
}
|
||||
|
||||
/// Returns a rotation representing this rotation followed by the other rotation.
|
||||
#[inline]
|
||||
pub fn post_rotate<NewDst>(
|
||||
&self,
|
||||
other: &Rotation2D<T, Dst, NewDst>,
|
||||
) -> Rotation2D<T, Src, NewDst> {
|
||||
other.pre_rotate(self)
|
||||
}
|
||||
|
||||
/// Returns the given 2d point transformed by this rotation.
|
||||
///
|
||||
/// The input point must be use the unit Src, and the returned point has the unit Dst.
|
||||
@ -213,7 +222,7 @@ where
|
||||
/// Returns the matrix representation of this rotation.
|
||||
#[inline]
|
||||
pub fn to_transform(&self) -> Transform2D<T, Src, Dst> {
|
||||
Transform2D::rotation(self.get_angle())
|
||||
Transform2D::create_rotation(self.get_angle())
|
||||
}
|
||||
}
|
||||
|
||||
@ -643,30 +652,38 @@ where
|
||||
let m32 = jk - ri;
|
||||
let m33 = one - (ii + jj);
|
||||
|
||||
Transform3D::new(
|
||||
m11, m12, m13, zero,
|
||||
m21, m22, m23, zero,
|
||||
m31, m32, m33, zero,
|
||||
zero, zero, zero, one,
|
||||
Transform3D::row_major(
|
||||
m11, m12, m13, zero, m21, m22, m23, zero, m31, m32, m33, zero, zero, zero, zero, one,
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns a rotation representing the other rotation followed by this rotation.
|
||||
pub fn pre_rotate<NewSrc>(
|
||||
&self,
|
||||
other: &Rotation3D<T, NewSrc, Src>,
|
||||
) -> Rotation3D<T, NewSrc, Dst>
|
||||
where
|
||||
T: ApproxEq<T>,
|
||||
{
|
||||
debug_assert!(self.is_normalized());
|
||||
Rotation3D::quaternion(
|
||||
self.i * other.r + self.r * other.i + self.j * other.k - self.k * other.j,
|
||||
self.j * other.r + self.r * other.j + self.k * other.i - self.i * other.k,
|
||||
self.k * other.r + self.r * other.k + self.i * other.j - self.j * other.i,
|
||||
self.r * other.r - self.i * other.i - self.j * other.j - self.k * other.k,
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns a rotation representing this rotation followed by the other rotation.
|
||||
#[inline]
|
||||
pub fn then<NewDst>(
|
||||
pub fn post_rotate<NewDst>(
|
||||
&self,
|
||||
other: &Rotation3D<T, Dst, NewDst>,
|
||||
) -> Rotation3D<T, Src, NewDst>
|
||||
where
|
||||
T: ApproxEq<T>,
|
||||
{
|
||||
debug_assert!(self.is_normalized());
|
||||
Rotation3D::quaternion(
|
||||
other.i * self.r + other.r * self.i + other.j * self.k - other.k * self.j,
|
||||
other.j * self.r + other.r * self.j + other.k * self.i - other.i * self.k,
|
||||
other.k * self.r + other.r * self.k + other.i * self.j - other.j * self.i,
|
||||
other.r * self.r - other.i * self.i - other.j * self.j - other.k * self.k,
|
||||
)
|
||||
other.pre_rotate(self)
|
||||
}
|
||||
|
||||
// add, sub and mul are used internally for intermediate computation but aren't public
|
||||
@ -713,6 +730,16 @@ impl<T: fmt::Debug, Src, Dst> fmt::Debug for Rotation3D<T, Src, Dst> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: fmt::Display, Src, Dst> fmt::Display for Rotation3D<T, Src, Dst> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"Quat({}*i + {}*j + {}*k + {})",
|
||||
self.i, self.j, self.k, self.r
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Src, Dst> ApproxEq<T> for Rotation3D<T, Src, Dst>
|
||||
where
|
||||
T: Copy + Neg<Output = T> + ApproxEq<T>,
|
||||
@ -810,18 +837,18 @@ fn pre_post() {
|
||||
|
||||
// Check that the order of transformations is correct (corresponds to what
|
||||
// we do in Transform3D).
|
||||
let p1 = r1.then(&r2).then(&r3).transform_point3d(p);
|
||||
let p1 = r1.post_rotate(&r2).post_rotate(&r3).transform_point3d(p);
|
||||
let p2 = t1
|
||||
.then(&t2)
|
||||
.then(&t3)
|
||||
.post_transform(&t2)
|
||||
.post_transform(&t3)
|
||||
.transform_point3d(p);
|
||||
|
||||
assert!(p1.approx_eq(&p2.unwrap()));
|
||||
|
||||
// Check that changing the order indeed matters.
|
||||
let p3 = t3
|
||||
.then(&t1)
|
||||
.then(&t2)
|
||||
.post_transform(&t1)
|
||||
.post_transform(&t2)
|
||||
.transform_point3d(p);
|
||||
assert!(!p1.approx_eq(&p3.unwrap()));
|
||||
}
|
||||
@ -991,7 +1018,7 @@ fn from_euler() {
|
||||
// Now check that the yaw pitch and roll transformations when combined are applied in
|
||||
// the proper order: roll -> pitch -> yaw.
|
||||
let ypr_e = Rotation3D::euler(angle, angle, angle);
|
||||
let ypr_q = roll_rq.then(&pitch_rq).then(&yaw_rq);
|
||||
let ypr_q = roll_rq.post_rotate(&pitch_rq).post_rotate(&yaw_rq);
|
||||
let ypr_pe = ypr_e.transform_point3d(p);
|
||||
let ypr_pq = ypr_q.transform_point3d(p);
|
||||
|
||||
|
103
third_party/rust/euclid/src/scale.rs
vendored
@ -10,12 +10,12 @@
|
||||
|
||||
use crate::num::One;
|
||||
|
||||
use crate::{Point2D, Point3D, Rect, Size2D, Vector2D, Box2D, Box3D};
|
||||
use crate::{Point2D, Rect, Size2D, Vector2D};
|
||||
use core::cmp::Ordering;
|
||||
use core::fmt;
|
||||
use core::hash::{Hash, Hasher};
|
||||
use core::marker::PhantomData;
|
||||
use core::ops::{Add, Div, Mul, Sub};
|
||||
use core::ops::{Add, Div, Mul, Neg, Sub};
|
||||
use num_traits::NumCast;
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -56,15 +56,6 @@ impl<T, Src, Dst> Scale<T, Src, Dst> {
|
||||
Scale(x, PhantomData)
|
||||
}
|
||||
|
||||
/// Creates an identity scale (1.0).
|
||||
#[inline]
|
||||
pub fn identity() -> Self
|
||||
where
|
||||
T: One
|
||||
{
|
||||
Scale::new(T::one())
|
||||
}
|
||||
|
||||
/// Returns the given point transformed by this scale.
|
||||
///
|
||||
/// # Example
|
||||
@ -79,20 +70,11 @@ impl<T, Src, Dst> Scale<T, Src, Dst> {
|
||||
/// assert_eq!(to_mm.transform_point(point2(42, -42)), point2(420, -420));
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn transform_point(self, point: Point2D<T, Src>) -> Point2D<T::Output, Dst>
|
||||
pub fn transform_point(&self, point: Point2D<T, Src>) -> Point2D<T::Output, Dst>
|
||||
where
|
||||
T: Copy + Mul,
|
||||
T: Clone + Mul,
|
||||
{
|
||||
Point2D::new(point.x * self.0, point.y * self.0)
|
||||
}
|
||||
|
||||
/// Returns the given point transformed by this scale.
|
||||
#[inline]
|
||||
pub fn transform_point3d(self, point: Point3D<T, Src>) -> Point3D<T::Output, Dst>
|
||||
where
|
||||
T: Copy + Mul,
|
||||
{
|
||||
Point3D::new(point.x * self.0, point.y * self.0, point.z * self.0)
|
||||
Point2D::new(point.x * self.get(), point.y * self.get())
|
||||
}
|
||||
|
||||
/// Returns the given vector transformed by this scale.
|
||||
@ -109,11 +91,11 @@ impl<T, Src, Dst> Scale<T, Src, Dst> {
|
||||
/// assert_eq!(to_mm.transform_vector(vec2(42, -42)), vec2(420, -420));
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn transform_vector(self, vec: Vector2D<T, Src>) -> Vector2D<T::Output, Dst>
|
||||
pub fn transform_vector(&self, vec: Vector2D<T, Src>) -> Vector2D<T::Output, Dst>
|
||||
where
|
||||
T: Copy + Mul,
|
||||
T: Clone + Mul,
|
||||
{
|
||||
Vector2D::new(vec.x * self.0, vec.y * self.0)
|
||||
Vector2D::new(vec.x * self.get(), vec.y * self.get())
|
||||
}
|
||||
|
||||
/// Returns the given vector transformed by this scale.
|
||||
@ -130,11 +112,11 @@ impl<T, Src, Dst> Scale<T, Src, Dst> {
|
||||
/// assert_eq!(to_mm.transform_size(size2(42, -42)), size2(420, -420));
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn transform_size(self, size: Size2D<T, Src>) -> Size2D<T::Output, Dst>
|
||||
pub fn transform_size(&self, size: Size2D<T, Src>) -> Size2D<T::Output, Dst>
|
||||
where
|
||||
T: Copy + Mul,
|
||||
T: Clone + Mul,
|
||||
{
|
||||
Size2D::new(size.width * self.0, size.height * self.0)
|
||||
Size2D::new(size.width * self.get(), size.height * self.get())
|
||||
}
|
||||
|
||||
/// Returns the given rect transformed by this scale.
|
||||
@ -151,7 +133,7 @@ impl<T, Src, Dst> Scale<T, Src, Dst> {
|
||||
/// assert_eq!(to_mm.transform_rect(&rect(1, 2, 42, -42)), rect(10, 20, 420, -420));
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn transform_rect(self, rect: &Rect<T, Src>) -> Rect<T::Output, Dst>
|
||||
pub fn transform_rect(&self, rect: &Rect<T, Src>) -> Rect<T::Output, Dst>
|
||||
where
|
||||
T: Copy + Mul,
|
||||
{
|
||||
@ -161,28 +143,13 @@ impl<T, Src, Dst> Scale<T, Src, Dst> {
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns the given box transformed by this scale.
|
||||
/// Returns the inverse of this scale.
|
||||
#[inline]
|
||||
pub fn transform_box2d(self, b: &Box2D<T, Src>) -> Box2D<T::Output, Dst>
|
||||
pub fn inverse(&self) -> Scale<T::Output, Dst, Src>
|
||||
where
|
||||
T: Copy + Mul,
|
||||
T: Clone + Neg,
|
||||
{
|
||||
Box2D {
|
||||
min: self.transform_point(b.min),
|
||||
max: self.transform_point(b.max),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the given box transformed by this scale.
|
||||
#[inline]
|
||||
pub fn transform_box3d(self, b: &Box3D<T, Src>) -> Box3D<T::Output, Dst>
|
||||
where
|
||||
T: Copy + Mul,
|
||||
{
|
||||
Box3D {
|
||||
min: self.transform_point3d(b.min),
|
||||
max: self.transform_point3d(b.max),
|
||||
}
|
||||
Scale::new(-self.get())
|
||||
}
|
||||
|
||||
/// Returns `true` if this scale has no effect.
|
||||
@ -203,17 +170,18 @@ impl<T, Src, Dst> Scale<T, Src, Dst> {
|
||||
/// assert_eq!(mm_per_mm, Scale::one());
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn is_identity(self) -> bool
|
||||
pub fn is_identity(&self) -> bool
|
||||
where
|
||||
T: PartialEq + One,
|
||||
{
|
||||
self.0 == T::one()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the underlying scalar scale factor.
|
||||
impl<T: Clone, Src, Dst> Scale<T, Src, Dst> {
|
||||
#[inline]
|
||||
pub fn get(self) -> T {
|
||||
self.0
|
||||
pub fn get(&self) -> T {
|
||||
self.0.clone()
|
||||
}
|
||||
|
||||
/// The inverse Scale (1.0 / self).
|
||||
@ -227,18 +195,18 @@ impl<T, Src, Dst> Scale<T, Src, Dst> {
|
||||
///
|
||||
/// let cm_per_mm: Scale<f32, Cm, Mm> = Scale::new(0.1);
|
||||
///
|
||||
/// assert_eq!(cm_per_mm.inverse(), Scale::new(10.0));
|
||||
/// assert_eq!(cm_per_mm.inv(), Scale::new(10.0));
|
||||
/// ```
|
||||
pub fn inverse(self) -> Scale<T::Output, Dst, Src>
|
||||
pub fn inv(&self) -> Scale<T::Output, Dst, Src>
|
||||
where
|
||||
T: One + Div,
|
||||
{
|
||||
let one: T = One::one();
|
||||
Scale::new(one / self.0)
|
||||
Scale::new(one / self.0.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: NumCast, Src, Dst> Scale<T, Src, Dst> {
|
||||
impl<T: NumCast + Clone, Src, Dst> Scale<T, Src, Dst> {
|
||||
/// Cast from one numeric representation to another, preserving the units.
|
||||
///
|
||||
/// # Panics
|
||||
@ -267,7 +235,7 @@ impl<T: NumCast, Src, Dst> Scale<T, Src, Dst> {
|
||||
/// let to_em: Scale<i32, Mm, Em> = Scale::new(10e20).cast();
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn cast<NewT: NumCast>(self) -> Scale<NewT, Src, Dst> {
|
||||
pub fn cast<NewT: NumCast>(&self) -> Scale<NewT, Src, Dst> {
|
||||
self.try_cast().unwrap()
|
||||
}
|
||||
|
||||
@ -290,11 +258,16 @@ impl<T: NumCast, Src, Dst> Scale<T, Src, Dst> {
|
||||
/// // Integer to small to store that number
|
||||
/// assert_eq!(to_em.try_cast::<i32>(), None);
|
||||
/// ```
|
||||
pub fn try_cast<NewT: NumCast>(self) -> Option<Scale<NewT, Src, Dst>> {
|
||||
NumCast::from(self.0).map(Scale::new)
|
||||
pub fn try_cast<NewT: NumCast>(&self) -> Option<Scale<NewT, Src, Dst>> {
|
||||
NumCast::from(self.get()).map(Scale::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Src, Dst> Scale<f32, Src, Dst> {
|
||||
/// Identity scaling, could be used to safely transit from one space to another.
|
||||
pub const ONE: Self = Scale(1.0, PhantomData);
|
||||
}
|
||||
|
||||
// scale0 * scale1
|
||||
// (A,B) * (B,C) = (A,C)
|
||||
impl<T: Mul, A, B, C> Mul<Scale<T, B, C>> for Scale<T, A, B> {
|
||||
@ -351,7 +324,7 @@ impl<T: Ord, Src, Dst> Ord for Scale<T, Src, Dst> {
|
||||
|
||||
impl<T: Clone, Src, Dst> Clone for Scale<T, Src, Dst> {
|
||||
fn clone(&self) -> Scale<T, Src, Dst> {
|
||||
Scale::new(self.0.clone())
|
||||
Scale::new(self.get())
|
||||
}
|
||||
}
|
||||
|
||||
@ -363,6 +336,12 @@ impl<T: fmt::Debug, Src, Dst> fmt::Debug for Scale<T, Src, Dst> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: fmt::Display, Src, Dst> fmt::Display for Scale<T, Src, Dst> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default, Src, Dst> Default for Scale<T, Src, Dst> {
|
||||
fn default() -> Self {
|
||||
Self::new(T::default())
|
||||
@ -395,7 +374,7 @@ mod tests {
|
||||
let mm_per_inch: Scale<f32, Inch, Mm> = Scale::new(25.4);
|
||||
let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
|
||||
|
||||
let mm_per_cm: Scale<f32, Cm, Mm> = cm_per_mm.inverse();
|
||||
let mm_per_cm: Scale<f32, Cm, Mm> = cm_per_mm.inv();
|
||||
assert_eq!(mm_per_cm.get(), 10.0);
|
||||
|
||||
let one: Scale<f32, Mm, Mm> = cm_per_mm * mm_per_cm;
|
||||
|