Bug 1567241 - Update to euclid 0.20. r=kvark, emilio.

Differential Revision: https://phabricator.services.mozilla.com/D38530

--HG--
extra : source : d65512e23a13164f540430ff0c85a1f2a147d8a0
This commit is contained in:
Nicolas Silva 2019-07-18 22:54:16 +02:00
Родитель 97bc08cce4
Коммит a58ba90d31
105 изменённых файлов: 3271 добавлений и 2915 удалений

40
Cargo.lock сгенерированный
Просмотреть файл

@ -1063,24 +1063,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "euclid"
version = "0.19.9"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"euclid_macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "euclid_macros"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "failure"
version = "0.1.3"
@ -1749,7 +1738,7 @@ version = "0.0.1"
dependencies = [
"app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.25.7 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hashglobe 0.1.0",
"selectors 0.21.0",
"servo_arc 0.1.1",
@ -2229,7 +2218,7 @@ dependencies = [
name = "peek-poke"
version = "0.2.0"
dependencies = [
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"peek-poke-derive 0.2.0",
]
@ -2301,11 +2290,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "plane-split"
version = "0.13.8"
version = "0.14.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.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -2979,7 +2968,7 @@ dependencies = [
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.25.7 (registry+https://github.com/rust-lang/crates.io-index)",
"derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fallible 0.0.1",
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hashglobe 0.1.0",
@ -3040,7 +3029,7 @@ dependencies = [
"app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.25.7 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"malloc_size_of 0.0.1",
"malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3651,7 +3640,7 @@ dependencies = [
"core-text 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cstr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"freetype 0.4.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.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3661,7 +3650,7 @@ dependencies = [
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"plane-split 0.13.8 (registry+https://github.com/rust-lang/crates.io-index)",
"plane-split 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ron 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3687,7 +3676,7 @@ dependencies = [
"core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
"derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"peek-poke 0.2.0",
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3706,7 +3695,7 @@ dependencies = [
"core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"foreign-types 0.3.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.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3803,7 +3792,7 @@ name = "wr_malloc_size_of"
version = "0.0.1"
dependencies = [
"app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -4003,8 +3992,7 @@ dependencies = [
"checksum encoding_rs 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)" = "4155785c79f2f6701f185eb2e6b4caf0555ec03477cb4c70db67b465311620ed"
"checksum env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0561146661ae44c579e993456bc76d11ce1e0c7d745e57b2fa7146b6e49fa2ad"
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
"checksum euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)" = "596b99621b9477e7a5f94d2d8dd13a9c5c302ac358b822c67a42b6f1054450e1"
"checksum euclid_macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdcb84c18ea5037a1c5a23039b4ff29403abce2e0d6b1daa11cf0bde2b30be15"
"checksum euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4786521fec183792e755bf32cd0188e4e7628c6d0fcfd51426435b9081a106"
"checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7"
"checksum failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596"
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
@ -4108,7 +4096,7 @@ dependencies = [
"checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2"
"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
"checksum plain 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
"checksum plane-split 0.13.8 (registry+https://github.com/rust-lang/crates.io-index)" = "91c621d83b9c5a85b7ca7ca2bec643136debb327ad29d0a08768db1325780365"
"checksum plane-split 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91821c7436aefc1b912552d494232efcaf9810c0189918749532be1e9dbace59"
"checksum plist 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "95bef0807b4fe77618f8d24f0c4ec37a4ad1dad9348c3b27d8b624c824d8cf48"
"checksum png 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9adebf7fb91ccf5eac9da1a8e00e83cb8ae882c3e8d8e4ad59da73cb8c82a2c9"
"checksum podio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e5422a1ee1bc57cc47ae717b0137314258138f38fd5f3cea083f43a9725383a0"

Просмотреть файл

@ -11,7 +11,7 @@ webrender_debugger = ["webrender/debugger"]
rayon = "1"
num_cpus = "1.7.0"
thread_profiler = "0.1.1"
euclid = { version = "0.19.4", features = ["serde"] }
euclid = { version = "0.20.0", features = ["serde"] }
app_units = "0.7"
gleam = "0.6.14"
log = "0.4"

Просмотреть файл

@ -388,7 +388,7 @@ static bool Moz2DRenderCallback(const Range<const uint8_t> aBlob,
auto bounds = gfx::IntRect(origin, aSize);
if (aDirtyRect) {
Rect dirty(aDirtyRect->origin.x, aDirtyRect->origin.y,
gfx::Rect dirty(aDirtyRect->origin.x, aDirtyRect->origin.y,
aDirtyRect->size.width, aDirtyRect->size.height);
dt->PushClipRect(dirty);
bounds = bounds.Intersect(

Просмотреть файл

@ -1138,10 +1138,10 @@ void DisplayListBuilder::PushBorderGradient(
const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip,
bool aIsBackfaceVisible, const wr::LayoutSideOffsets& aWidths,
const int32_t aWidth, const int32_t aHeight, bool aFill,
const wr::SideOffsets2D<int32_t>& aSlice,
const wr::DeviceIntSideOffsets& aSlice,
const wr::LayoutPoint& aStartPoint, const wr::LayoutPoint& aEndPoint,
const nsTArray<wr::GradientStop>& aStops, wr::ExtendMode aExtendMode,
const wr::SideOffsets2D<float>& aOutset) {
const wr::LayoutSideOffsets& aOutset) {
wr_dp_push_border_gradient(mWrState, aBounds, MergeClipLeaf(aClip),
aIsBackfaceVisible, &mCurrentSpaceAndClipChain,
aWidths, aWidth, aHeight, aFill, aSlice,
@ -1154,7 +1154,7 @@ void DisplayListBuilder::PushBorderRadialGradient(
bool aIsBackfaceVisible, const wr::LayoutSideOffsets& aWidths, bool aFill,
const wr::LayoutPoint& aCenter, const wr::LayoutSize& aRadius,
const nsTArray<wr::GradientStop>& aStops, wr::ExtendMode aExtendMode,
const wr::SideOffsets2D<float>& aOutset) {
const wr::LayoutSideOffsets& aOutset) {
wr_dp_push_border_radial_gradient(
mWrState, aBounds, MergeClipLeaf(aClip), aIsBackfaceVisible,
&mCurrentSpaceAndClipChain, aWidths, aFill, aCenter, aRadius,

Просмотреть файл

@ -511,19 +511,19 @@ class DisplayListBuilder final {
const wr::LayoutRect& aClip, bool aIsBackfaceVisible,
const wr::LayoutSideOffsets& aWidths,
const int32_t aWidth, const int32_t aHeight,
bool aFill, const wr::SideOffsets2D<int32_t>& aSlice,
bool aFill, const wr::DeviceIntSideOffsets& aSlice,
const wr::LayoutPoint& aStartPoint,
const wr::LayoutPoint& aEndPoint,
const nsTArray<wr::GradientStop>& aStops,
wr::ExtendMode aExtendMode,
const wr::SideOffsets2D<float>& aOutset);
const wr::LayoutSideOffsets& aOutset);
void PushBorderRadialGradient(
const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip,
bool aIsBackfaceVisible, const wr::LayoutSideOffsets& aWidths, bool aFill,
const wr::LayoutPoint& aCenter, const wr::LayoutSize& aRadius,
const nsTArray<wr::GradientStop>& aStops, wr::ExtendMode aExtendMode,
const wr::SideOffsets2D<float>& aOutset);
const wr::LayoutSideOffsets& aOutset);
void PushText(const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip,
bool aIsBackfaceVisible, const wr::ColorF& aColor,

Просмотреть файл

@ -627,11 +627,11 @@ static inline wr::LayoutSideOffsets ToBorderWidths(float top, float right,
return bw;
}
static inline wr::SideOffsets2D<int32_t> ToSideOffsets2D_i32(int32_t top,
int32_t right,
int32_t bottom,
int32_t left) {
SideOffsets2D<int32_t> offset;
static inline wr::DeviceIntSideOffsets ToDeviceIntSideOffsets(int32_t top,
int32_t right,
int32_t bottom,
int32_t left) {
wr::DeviceIntSideOffsets offset;
offset.top = top;
offset.right = right;
offset.bottom = bottom;
@ -639,11 +639,11 @@ static inline wr::SideOffsets2D<int32_t> ToSideOffsets2D_i32(int32_t top,
return offset;
}
static inline wr::SideOffsets2D<float> ToSideOffsets2D_f32(float top,
float right,
float bottom,
float left) {
SideOffsets2D<float> offset;
static inline wr::LayoutSideOffsets ToLayoutSideOffsets(float top,
float right,
float bottom,
float left) {
wr::LayoutSideOffsets offset;
offset.top = top;
offset.right = right;
offset.bottom = bottom;

Просмотреть файл

@ -2780,8 +2780,8 @@ pub struct WrBorderImage {
width: i32,
height: i32,
fill: bool,
slice: SideOffsets2D<i32>,
outset: SideOffsets2D<f32>,
slice: DeviceIntSideOffsets,
outset: LayoutSideOffsets,
repeat_horizontal: RepeatMode,
repeat_vertical: RepeatMode,
}
@ -2832,13 +2832,13 @@ pub extern "C" fn wr_dp_push_border_gradient(state: &mut WrState,
width: i32,
height: i32,
fill: bool,
slice: SideOffsets2D<i32>,
slice: DeviceIntSideOffsets,
start_point: LayoutPoint,
end_point: LayoutPoint,
stops: *const GradientStop,
stops_count: usize,
extend_mode: ExtendMode,
outset: SideOffsets2D<f32>) {
outset: LayoutSideOffsets) {
debug_assert!(unsafe { is_in_main_thread() });
let stops_slice = unsafe { make_slice(stops, stops_count) };
@ -2893,7 +2893,7 @@ pub extern "C" fn wr_dp_push_border_radial_gradient(state: &mut WrState,
stops: *const GradientStop,
stops_count: usize,
extend_mode: ExtendMode,
outset: SideOffsets2D<f32>) {
outset: LayoutSideOffsets) {
debug_assert!(unsafe { is_in_main_thread() });
let stops_slice = unsafe { make_slice(stops, stops_count) };

38
gfx/wr/Cargo.lock сгенерированный
Просмотреть файл

@ -423,7 +423,7 @@ dependencies = [
name = "direct-composition"
version = "0.1.0"
dependencies = [
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
"mozangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"webrender 0.60.0",
@ -480,24 +480,13 @@ dependencies = [
[[package]]
name = "euclid"
version = "0.19.9"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"euclid_macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "euclid_macros"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "expat-sys"
version = "2.1.5"
@ -1140,7 +1129,7 @@ dependencies = [
name = "peek-poke"
version = "0.2.0"
dependencies = [
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"peek-poke-derive 0.2.0",
]
@ -1167,11 +1156,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "plane-split"
version = "0.13.8"
version = "0.14.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.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1883,7 +1872,7 @@ dependencies = [
"core-text 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cstr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"freetype 0.4.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.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1894,7 +1883,7 @@ dependencies = [
"malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"mozangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"plane-split 0.13.8 (registry+https://github.com/rust-lang/crates.io-index)",
"plane-split 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"png 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1918,7 +1907,7 @@ version = "0.1.0"
dependencies = [
"app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
"glutin 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1936,7 +1925,7 @@ dependencies = [
"core-foundation 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)",
"derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"peek-poke 0.2.0",
@ -2028,7 +2017,7 @@ name = "wr_malloc_size_of"
version = "0.0.1"
dependencies = [
"app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -2045,7 +2034,7 @@ dependencies = [
"crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"font-loader 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
"glutin 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2189,8 +2178,7 @@ dependencies = [
"checksum dwrote 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0bd1369e02db5e9b842a9b67bce8a2fcc043beafb2ae8a799dd482d46ea1ff0d"
"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
"checksum env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0e6e40ebb0e66918a37b38c7acab4e10d299e0463fe2af5d29b9cc86710cfd2a"
"checksum euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)" = "596b99621b9477e7a5f94d2d8dd13a9c5c302ac358b822c67a42b6f1054450e1"
"checksum euclid_macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdcb84c18ea5037a1c5a23039b4ff29403abce2e0d6b1daa11cf0bde2b30be15"
"checksum euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4786521fec183792e755bf32cd0188e4e7628c6d0fcfd51426435b9081a106"
"checksum expat-sys 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c470ccb972f2088549b023db8029ed9da9426f5affbf9b62efff7009ab8ed5b1"
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
@ -2268,7 +2256,7 @@ dependencies = [
"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9"
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
"checksum pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "110d5ee3593dbb73f56294327fe5668bcc997897097cbc76b51e7aed3f52452f"
"checksum plane-split 0.13.8 (registry+https://github.com/rust-lang/crates.io-index)" = "91c621d83b9c5a85b7ca7ca2bec643136debb327ad29d0a08768db1325780365"
"checksum plane-split 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91821c7436aefc1b912552d494232efcaf9810c0189918749532be1e9dbace59"
"checksum png 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9adebf7fb91ccf5eac9da1a8e00e83cb8ae882c3e8d8e4ad59da73cb8c82a2c9"
"checksum proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)" = "d3797b7142c9aa74954e351fc089bbee7958cebbff6bf2815e7ffff0b19f547d"
"checksum procedural-masquerade 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9a1574a51c3fd37b26d2c0032b649d08a7d51d4cca9c41bbc5bf7118fa4509d0"

Просмотреть файл

@ -6,7 +6,7 @@ license = "MPL-2.0"
edition = "2018"
[target.'cfg(windows)'.dependencies]
euclid = "0.19"
euclid = "0.20"
gleam = "0.6.2"
mozangle = {version = "0.1", features = ["egl"]}
webrender = {path = "../webrender"}

Просмотреть файл

@ -133,10 +133,10 @@ impl Rectangle {
self.visual.make_current();
let pipeline_id = api::PipelineId(0, 0);
let layout_size = self.size.to_f32() / euclid::TypedScale::new(device_pixel_ratio);
let layout_size = self.size.to_f32() / euclid::Scale::new(device_pixel_ratio);
let mut builder = api::DisplayListBuilder::new(pipeline_id, layout_size);
let rect = euclid::TypedRect::new(euclid::TypedPoint2D::zero(), layout_size);
let rect = euclid::Rect::new(euclid::Point2D::zero(), layout_size);
let region = api::ComplexClipRegion::new(
rect,

Просмотреть файл

@ -60,7 +60,7 @@ debug = ["webrender/capture", "webrender/debugger", "webrender/profiler"]
[dependencies]
app_units = "0.7"
env_logger = "0.5"
euclid = "0.19"
euclid = "0.20"
gleam = "0.6.2"
glutin = "0.21"
rayon = "1"

Просмотреть файл

@ -192,7 +192,7 @@ pub fn main_wrapper<E: Example>(
let epoch = Epoch(0);
let pipeline_id = PipelineId(0, 0);
let layout_size = device_size.to_f32() / euclid::TypedScale::new(device_pixel_ratio);
let layout_size = device_size.to_f32() / euclid::Scale::new(device_pixel_ratio);
let mut builder = DisplayListBuilder::new(pipeline_id, layout_size);
let mut txn = Transaction::new();

Просмотреть файл

@ -12,7 +12,7 @@ extern crate winit;
mod boilerplate;
use crate::boilerplate::Example;
use euclid::TypedScale;
use euclid::Scale;
use webrender::api::*;
use webrender::api::units::*;
@ -78,7 +78,7 @@ impl App {
pipeline_id,
content_rect: LayoutRect::new(
LayoutPoint::origin(),
bounds.size.to_f32() / TypedScale::new(device_pixel_ratio),
bounds.size.to_f32() / Scale::new(device_pixel_ratio),
),
color,
});

Просмотреть файл

@ -12,7 +12,7 @@ extern crate winit;
mod boilerplate;
use crate::boilerplate::{Example, HandyDandyRectBuilder};
use euclid::TypedScale;
use euclid::Scale;
use gleam::gl;
use webrender::api::*;
use webrender::api::units::*;
@ -92,7 +92,7 @@ impl App {
pipeline_id,
content_rect: LayoutRect::new(
LayoutPoint::zero(),
device_size.to_f32() / TypedScale::new(device_pixel_ratio),
device_size.to_f32() / Scale::new(device_pixel_ratio),
),
color,
};

Просмотреть файл

@ -181,7 +181,7 @@ impl Window {
.to_physical(device_pixel_ratio as f64);
DeviceIntSize::new(size.width as i32, size.height as i32)
};
let layout_size = device_size.to_f32() / euclid::TypedScale::new(device_pixel_ratio);
let layout_size = device_size.to_f32() / euclid::Scale::new(device_pixel_ratio);
let mut txn = Transaction::new();
let mut builder = DisplayListBuilder::new(self.pipeline_id, layout_size);
let space_and_clip = SpaceAndClipInfo::root_scroll(self.pipeline_id);

Просмотреть файл

@ -6,7 +6,7 @@ license = "MIT/Apache-2.0"
edition = "2018"
[dependencies]
euclid = { version = "0.19", optional = true }
euclid = { version = "0.20.0", optional = true }
peek-poke-derive = { version = "0.2", path = "./peek-poke-derive", optional = true }
[features]

Просмотреть файл

@ -9,9 +9,9 @@
// except according to those terms.
use crate::{Peek, Poke};
use euclid::{TypedPoint2D, TypedRect, TypedSideOffsets2D, TypedSize2D, TypedTransform3D, TypedVector2D};
use euclid::{Point2D, Rect, SideOffsets2D, Size2D, Transform3D, Vector2D};
unsafe impl<T: Poke, U> Poke for TypedPoint2D<T, U> {
unsafe impl<T: Poke, U> Poke for Point2D<T, U> {
#[inline(always)]
fn max_size() -> usize {
2 * T::max_size()
@ -23,7 +23,7 @@ unsafe impl<T: Poke, U> Poke for TypedPoint2D<T, U> {
bytes
}
}
impl<T: Peek, U> Peek for TypedPoint2D<T, U> {
impl<T: Peek, U> Peek for Point2D<T, U> {
#[inline(always)]
unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8 {
let bytes = T::peek_from(bytes, &mut (*output).x);
@ -32,10 +32,10 @@ impl<T: Peek, U> Peek for TypedPoint2D<T, U> {
}
}
unsafe impl<T: Poke, U> Poke for TypedRect<T, U> {
unsafe impl<T: Poke, U> Poke for Rect<T, U> {
#[inline(always)]
fn max_size() -> usize {
TypedPoint2D::<T, U>::max_size() + TypedSize2D::<T, U>::max_size()
Point2D::<T, U>::max_size() + Size2D::<T, U>::max_size()
}
#[inline(always)]
unsafe fn poke_into(&self, bytes: *mut u8) -> *mut u8 {
@ -44,16 +44,16 @@ unsafe impl<T: Poke, U> Poke for TypedRect<T, U> {
bytes
}
}
impl<T: Peek, U> Peek for TypedRect<T, U> {
impl<T: Peek, U> Peek for Rect<T, U> {
#[inline(always)]
unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8 {
let bytes = TypedPoint2D::<T, U>::peek_from(bytes, &mut (*output).origin);
let bytes = TypedSize2D::<T, U>::peek_from(bytes, &mut (*output).size);
let bytes = Point2D::<T, U>::peek_from(bytes, &mut (*output).origin);
let bytes = Size2D::<T, U>::peek_from(bytes, &mut (*output).size);
bytes
}
}
unsafe impl<T: Poke, U> Poke for TypedSideOffsets2D<T, U> {
unsafe impl<T: Poke, U> Poke for SideOffsets2D<T, U> {
#[inline(always)]
fn max_size() -> usize {
4 * T::max_size()
@ -67,7 +67,7 @@ unsafe impl<T: Poke, U> Poke for TypedSideOffsets2D<T, U> {
bytes
}
}
impl<T: Peek, U> Peek for TypedSideOffsets2D<T, U> {
impl<T: Peek, U> Peek for SideOffsets2D<T, U> {
#[inline(always)]
unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8 {
let bytes = T::peek_from(bytes, &mut (*output).top);
@ -78,7 +78,7 @@ impl<T: Peek, U> Peek for TypedSideOffsets2D<T, U> {
}
}
unsafe impl<T: Poke, U> Poke for TypedSize2D<T, U> {
unsafe impl<T: Poke, U> Poke for Size2D<T, U> {
#[inline(always)]
fn max_size() -> usize {
2 * T::max_size()
@ -90,7 +90,7 @@ unsafe impl<T: Poke, U> Poke for TypedSize2D<T, U> {
bytes
}
}
impl<T: Peek, U> Peek for TypedSize2D<T, U> {
impl<T: Peek, U> Peek for Size2D<T, U> {
#[inline(always)]
unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8 {
let bytes = T::peek_from(bytes, &mut (*output).width);
@ -99,7 +99,7 @@ impl<T: Peek, U> Peek for TypedSize2D<T, U> {
}
}
unsafe impl<T: Poke, S, D> Poke for TypedTransform3D<T, S, D> {
unsafe impl<T: Poke, S, D> Poke for Transform3D<T, S, D> {
#[inline(always)]
fn max_size() -> usize {
16 * T::max_size()
@ -125,7 +125,7 @@ unsafe impl<T: Poke, S, D> Poke for TypedTransform3D<T, S, D> {
bytes
}
}
impl<T: Peek, S, D> Peek for TypedTransform3D<T, S, D> {
impl<T: Peek, S, D> Peek for Transform3D<T, S, D> {
#[inline(always)]
unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8 {
let bytes = T::peek_from(bytes, &mut (*output).m11);
@ -148,7 +148,7 @@ impl<T: Peek, S, D> Peek for TypedTransform3D<T, S, D> {
}
}
unsafe impl<T: Poke, U> Poke for TypedVector2D<T, U> {
unsafe impl<T: Poke, U> Poke for Vector2D<T, U> {
#[inline(always)]
fn max_size() -> usize {
2 * T::max_size()
@ -160,7 +160,7 @@ unsafe impl<T: Poke, U> Poke for TypedVector2D<T, U> {
bytes
}
}
impl<T: Peek, U> Peek for TypedVector2D<T, U> {
impl<T: Peek, U> Peek for Vector2D<T, U> {
#[inline(always)]
unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8 {
let bytes = T::peek_from(bytes, &mut (*output).x);

Просмотреть файл

@ -29,7 +29,7 @@ bitflags = "1.0"
byteorder = "1.0"
cfg-if = "0.1.2"
cstr = "0.1.2"
euclid = { version = "0.19.5", features = ["serde"] }
euclid = { version = "0.20.0", features = ["serde"] }
fxhash = "0.2.1"
gleam = "0.6.17"
image_loader = { optional = true, version = "0.21", package = "image", default-features = false, features = ["png_codec"] }
@ -37,7 +37,7 @@ lazy_static = "1"
log = "0.4"
malloc_size_of_derive = "0.1"
num-traits = "0.2"
plane-split = "0.13.7"
plane-split = "0.14.0"
png = { optional = true, version = "0.14" }
rayon = "1"
ron = { optional = true, version = "0.1.7" }

Просмотреть файл

@ -1336,7 +1336,7 @@ impl BatchBuilder {
// Get the GPU cache address of the extra data handle.
let shadow_prim_address = gpu_cache.get_address(shadow_gpu_data);
let shadow_rect = prim_header.local_rect.translate(&shadow.offset);
let shadow_rect = prim_header.local_rect.translate(shadow.offset);
let shadow_prim_header = PrimitiveHeader {
local_rect: shadow_rect,
@ -2081,7 +2081,7 @@ impl BatchBuilder {
gpu_blocks.push([-1.0, 0.0, 0.0, 0.0].into()); //stretch size
// negative first value makes the shader code ignore it and use the local size instead
for tile in chunk {
let tile_rect = tile.local_rect.translate(&-prim_rect.origin.to_vector());
let tile_rect = tile.local_rect.translate(-prim_rect.origin.to_vector());
gpu_blocks.push(tile_rect.into());
gpu_blocks.push(GpuBlockData::EMPTY);
}
@ -2909,7 +2909,7 @@ impl ClipBatcher {
p1.y - p0.y,
),
).to_f32();
let world_sub_rect = normalized_sub_rect.translate(&mask_origin);
let world_sub_rect = normalized_sub_rect.translate(mask_origin);
// If the clip rect completely contains this tile rect, then drawing
// these pixels would be redundant - since this clip can't possibly

Просмотреть файл

@ -1072,7 +1072,7 @@ fn add_corner_segment(
}
let texture_rect = segment_rect
.translate(&-image_rect.origin.to_vector())
.translate(-image_rect.origin.to_vector())
.scale(1.0 / image_rect.size.width, 1.0 / image_rect.size.height);
brush_segments.push(

Просмотреть файл

@ -100,7 +100,7 @@ impl<'a> DisplayListFlattener<'a> {
// exists in the local space of the primitive.
let shadow_rect = prim_info
.rect
.translate(box_offset)
.translate(*box_offset)
.inflate(spread_amount, spread_amount);
// If blur radius is zero, we can use a fast path with
@ -201,7 +201,7 @@ impl<'a> DisplayListFlattener<'a> {
let shadow_clip_source = ClipItemKey::box_shadow(
shadow_rect,
shadow_radius,
dest_rect.translate(&LayoutVector2D::new(-prim_info.rect.origin.x, -prim_info.rect.origin.y)),
dest_rect.translate(LayoutVector2D::new(-prim_info.rect.origin.x, -prim_info.rect.origin.y)),
blur_radius,
clip_mode,
);

Просмотреть файл

@ -958,7 +958,7 @@ impl<I: Iterator<Item = ComplexClipRegion>> Iterator for ComplexTranslateIter<I>
self.source
.next()
.map(|mut complex| {
complex.rect = complex.rect.translate(&self.offset);
complex.rect = complex.rect.translate(self.offset);
complex
})
}
@ -982,11 +982,11 @@ impl<J> ClipRegion<ComplexTranslateIter<J>> {
J: Iterator<Item = ComplexClipRegion>
{
if let Some(ref mut image_mask) = image_mask {
image_mask.rect = image_mask.rect.translate(reference_frame_relative_offset);
image_mask.rect = image_mask.rect.translate(*reference_frame_relative_offset);
}
ClipRegion {
main: rect.translate(reference_frame_relative_offset),
main: rect.translate(*reference_frame_relative_offset),
image_mask,
complex_clips: ComplexTranslateIter {
source: complex_clips,
@ -1002,7 +1002,7 @@ impl ClipRegion<Option<ComplexClipRegion>> {
reference_frame_relative_offset: &LayoutVector2D
) -> Self {
ClipRegion {
main: local_clip.translate(reference_frame_relative_offset),
main: local_clip.translate(*reference_frame_relative_offset),
image_mask: None,
complex_clips: None,
}
@ -1494,7 +1494,7 @@ pub fn rounded_rectangle_contains_point(
rect: &LayoutRect,
radii: &BorderRadius
) -> bool {
if !rect.contains(point) {
if !rect.contains(*point) {
return false;
}
@ -1532,10 +1532,10 @@ pub fn project_inner_rect(
rect: &LayoutRect,
) -> Option<WorldRect> {
let points = [
transform.transform_point2d(&rect.origin)?,
transform.transform_point2d(&rect.top_right())?,
transform.transform_point2d(&rect.bottom_left())?,
transform.transform_point2d(&rect.bottom_right())?,
transform.transform_point2d(rect.origin)?,
transform.transform_point2d(rect.top_right())?,
transform.transform_point2d(rect.bottom_left())?,
transform.transform_point2d(rect.bottom_right())?,
];
let mut xs = [points[0].x, points[1].x, points[2].x, points[3].x];

Просмотреть файл

@ -5,7 +5,7 @@
use api::{ExternalScrollId, PropertyBinding, ReferenceFrameKind, TransformStyle};
use api::{PipelineId, ScrollClamping, ScrollNodeState, ScrollLocation, ScrollSensitivity};
use api::units::*;
use euclid::TypedTransform3D;
use euclid::Transform3D;
use crate::gpu_types::TransformPalette;
use crate::internal_types::{FastHashMap, FastHashSet};
use crate::print_tree::{PrintableTree, PrintTree, PrintTreePrinter};
@ -146,13 +146,13 @@ pub struct TransformUpdateState {
pub enum CoordinateSpaceMapping<Src, Dst> {
Local,
ScaleOffset(ScaleOffset),
Transform(TypedTransform3D<f32, Src, Dst>),
Transform(Transform3D<f32, Src, Dst>),
}
impl<Src, Dst> CoordinateSpaceMapping<Src, Dst> {
pub fn into_transform(self) -> TypedTransform3D<f32, Src, Dst> {
pub fn into_transform(self) -> Transform3D<f32, Src, Dst> {
match self {
CoordinateSpaceMapping::Local => TypedTransform3D::identity(),
CoordinateSpaceMapping::Local => Transform3D::identity(),
CoordinateSpaceMapping::ScaleOffset(scale_offset) => scale_offset.to_transform(),
CoordinateSpaceMapping::Transform(transform) => transform,
}
@ -287,10 +287,10 @@ impl ClipScrollTree {
}
coordinate_system_id = coord_system.parent.expect("invalid parent!");
transform = transform.post_mul(&coord_system.transform);
transform = transform.post_transform(&coord_system.transform);
}
transform = transform.post_mul(
transform = transform.post_transform(
&parent.content_transform
.inverse()
.to_transform(),
@ -320,7 +320,7 @@ impl ClipScrollTree {
};
let transform = scale_offset
.to_transform()
.post_mul(&system.world_transform);
.post_transform(&system.world_transform);
CoordinateSpaceMapping::Transform(transform)
}
@ -715,7 +715,7 @@ fn test_pt(
let p = LayoutPoint::new(px, py);
let m = cst.get_relative_transform(child, parent).into_transform();
let pt = m.transform_point2d(&p).unwrap();
let pt = m.transform_point2d(p).unwrap();
assert!(pt.x.approx_eq_eps(&expected_x, &EPSILON) &&
pt.y.approx_eq_eps(&expected_y, &EPSILON),
"p: {:?} -> {:?}\nm={:?}",

Просмотреть файл

@ -7,7 +7,7 @@ use api::units::*;
use crate::debug_font_data;
use crate::device::{Device, Program, Texture, TextureSlot, VertexDescriptor, ShaderError, VAO};
use crate::device::{TextureFilter, VertexAttribute, VertexAttributeKind, VertexUsageHint};
use euclid::{Point2D, Rect, Size2D, Transform3D};
use euclid::{Point2D, Rect, Size2D, Transform3D, default};
use crate::internal_types::{ORTHO_FAR_PLANE, ORTHO_NEAR_PLANE};
use std::f32;
@ -193,7 +193,7 @@ impl DebugRenderer {
text: &str,
color: ColorU,
bounds: Option<DeviceRect>,
) -> Rect<f32> {
) -> default::Rect<f32> {
let mut x_start = x;
let ipw = 1.0 / debug_font_data::BMP_WIDTH as f32;
let iph = 1.0 / debug_font_data::BMP_HEIGHT as f32;

Просмотреть файл

@ -6,7 +6,7 @@ use super::super::shader_source::SHADERS;
use api::{ColorF, ImageDescriptor, ImageFormat, MemoryReport};
use api::{MixBlendMode, TextureTarget, VoidPtrToSizeFn};
use api::units::*;
use euclid::Transform3D;
use euclid::default::Transform3D;
use gleam::gl;
use crate::internal_types::{FastHashMap, LayerIndex, RenderTargetInfo};
use log::Level;
@ -1045,7 +1045,7 @@ pub enum DrawTarget {
impl DrawTarget {
pub fn new_default(size: DeviceIntSize) -> Self {
let total_size = FramebufferIntSize::from_untyped(&size.to_untyped());
let total_size = FramebufferIntSize::from_untyped(size.to_untyped());
DrawTarget::Default {
rect: total_size.into(),
total_size,
@ -1085,9 +1085,9 @@ impl DrawTarget {
/// Returns the dimensions of this draw-target.
pub fn dimensions(&self) -> DeviceIntSize {
match *self {
DrawTarget::Default { total_size, .. } => DeviceIntSize::from_untyped(&total_size.to_untyped()),
DrawTarget::Default { total_size, .. } => DeviceIntSize::from_untyped(total_size.to_untyped()),
DrawTarget::Texture { dimensions, .. } => dimensions,
DrawTarget::External { size, .. } => DeviceIntSize::from_untyped(&size.to_untyped()),
DrawTarget::External { size, .. } => DeviceIntSize::from_untyped(size.to_untyped()),
}
}
@ -1117,7 +1117,7 @@ impl DrawTarget {
match scissor_rect {
Some(scissor_rect) => match *self {
DrawTarget::Default { ref rect, .. } => {
self.to_framebuffer_rect(scissor_rect.translate(&-content_origin.to_vector()))
self.to_framebuffer_rect(scissor_rect.translate(-content_origin.to_vector()))
.intersection(rect)
.unwrap_or_else(FramebufferIntRect::zero)
}
@ -1128,7 +1128,7 @@ impl DrawTarget {
None => {
FramebufferIntRect::new(
FramebufferIntPoint::zero(),
FramebufferIntSize::from_untyped(&dimensions.to_untyped()),
FramebufferIntSize::from_untyped(dimensions.to_untyped()),
)
}
}
@ -1599,7 +1599,7 @@ impl Device {
DrawTarget::Texture { dimensions, fbo_id, with_depth, .. } => {
let rect = FramebufferIntRect::new(
FramebufferIntPoint::zero(),
FramebufferIntSize::from_untyped(&dimensions.to_untyped()),
FramebufferIntSize::from_untyped(dimensions.to_untyped()),
);
(fbo_id, rect, with_depth)
},
@ -2004,7 +2004,7 @@ impl Device {
} else {
let rect = FramebufferIntRect::new(
FramebufferIntPoint::zero(),
FramebufferIntSize::from_untyped(&src.get_dimensions().to_untyped()),
FramebufferIntSize::from_untyped(src.get_dimensions().to_untyped()),
);
for layer in 0..src.layer_count.min(dst.layer_count) as LayerIndex {
self.blit_render_target(

Просмотреть файл

@ -704,7 +704,7 @@ impl<'a> DisplayListFlattener<'a> {
parent_node_index: SpatialNodeIndex,
) {
let current_offset = self.current_offset(parent_node_index);
let frame_rect = info.bounds.translate(&current_offset);
let frame_rect = info.bounds.translate(current_offset);
let sticky_frame_info = StickyFrameInfo::new(
frame_rect,
info.margins,
@ -966,8 +966,8 @@ impl<'a> DisplayListFlattener<'a> {
let current_offset = self.current_offset(clip_and_scroll.spatial_node_index);
let clip_rect = common.clip_rect.translate(&current_offset);
let rect = bounds.translate(&current_offset);
let clip_rect = common.clip_rect.translate(current_offset);
let rect = bounds.translate(current_offset);
let layout = LayoutPrimitiveInfo {
rect,
clip_rect,
@ -2530,9 +2530,9 @@ impl<'a> DisplayListFlattener<'a> {
{
// Offset the local rect and clip rect by the shadow offset.
let mut info = pending_primitive.info.clone();
info.rect = info.rect.translate(&pending_shadow.shadow.offset);
info.rect = info.rect.translate(pending_shadow.shadow.offset);
info.clip_rect = info.clip_rect.translate(
&pending_shadow.shadow.offset
pending_shadow.shadow.offset
);
// Construct and add a primitive for the given shadow.

Просмотреть файл

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::units::*;
use euclid::TypedSize2D;
use euclid::Size2D;
use std::f32::consts::FRAC_PI_2;
@ -13,12 +13,12 @@ const STEP_COUNT: usize = 20;
/// Represents an ellipse centred at a local space origin.
#[derive(Debug, Clone)]
pub struct Ellipse<U> {
pub radius: TypedSize2D<f32, U>,
pub radius: Size2D<f32, U>,
pub total_arc_length: f32,
}
impl<U> Ellipse<U> {
pub fn new(radius: TypedSize2D<f32, U>) -> Ellipse<U> {
pub fn new(radius: Size2D<f32, U>) -> Ellipse<U> {
// Approximate the total length of the first quadrant of this ellipse.
let total_arc_length = get_simpson_length(FRAC_PI_2, radius.width, radius.height);

Просмотреть файл

@ -28,7 +28,7 @@ use api::{DebugFlags, DocumentId, PremultipliedColorF};
#[cfg(test)]
use api::IdNamespace;
use api::units::TexelRect;
use euclid::{HomogeneousVector, TypedRect};
use euclid::{HomogeneousVector, Rect};
use crate::internal_types::{FastHashMap, FastHashSet};
use crate::profiler::GpuCacheProfileCounters;
use crate::render_backend::{FrameStamp, FrameId};
@ -102,8 +102,8 @@ impl From<[f32; 4]> for GpuBlockData {
}
}
impl<P> From<TypedRect<f32, P>> for GpuBlockData {
fn from(r: TypedRect<f32, P>) -> Self {
impl<P> From<Rect<f32, P>> for GpuBlockData {
fn from(r: Rect<f32, P>) -> Self {
GpuBlockData {
data: [
r.origin.x,

Просмотреть файл

@ -197,9 +197,9 @@ impl HitTestRegion {
pub fn contains(&self, point: &LayoutPoint) -> bool {
match *self {
HitTestRegion::Rectangle(ref rectangle, ClipMode::Clip) =>
rectangle.contains(point),
rectangle.contains(*point),
HitTestRegion::Rectangle(ref rectangle, ClipMode::ClipOut) =>
!rectangle.contains(point),
!rectangle.contains(*point),
HitTestRegion::RoundedRectangle(rect, radii, ClipMode::Clip) =>
rounded_rectangle_contains_point(point, &rect, &radii),
HitTestRegion::RoundedRectangle(rect, radii, ClipMode::ClipOut) =>
@ -342,7 +342,7 @@ impl HitTester {
.world_content_transform;
let transformed_point = match transform
.inverse()
.and_then(|inverted| inverted.transform_point2d(&point))
.and_then(|inverted| inverted.transform_point2d(point))
{
Some(point) => point,
None => {
@ -375,7 +375,7 @@ impl HitTester {
point_in_layer = scroll_node
.world_content_transform
.inverse()
.and_then(|inverted| inverted.transform_point2d(&point));
.and_then(|inverted| inverted.transform_point2d(point));
current_spatial_node_index = item.spatial_node_index;
}
@ -384,10 +384,10 @@ impl HitTester {
if let Some(point_in_layer) = point_in_layer {
// If the item's rect or clip rect don't contain this point,
// it's not a valid hit.
if !item.rect.contains(&point_in_layer) {
if !item.rect.contains(point_in_layer) {
continue;
}
if !item.clip_rect.contains(&point_in_layer) {
if !item.clip_rect.contains(point_in_layer) {
continue;
}
@ -436,7 +436,7 @@ impl HitTester {
point_in_layer = scroll_node
.world_content_transform
.inverse()
.and_then(|inverted| inverted.transform_point2d(&point));
.and_then(|inverted| inverted.transform_point2d(point));
current_spatial_node_index = item.spatial_node_index;
}
@ -444,10 +444,10 @@ impl HitTester {
if let Some(point_in_layer) = point_in_layer {
// If the item's rect or clip rect don't contain this point,
// it's not a valid hit.
if !item.rect.contains(&point_in_layer) {
if !item.rect.contains(point_in_layer) {
continue;
}
if !item.clip_rect.contains(&point_in_layer) {
if !item.clip_rect.contains(point_in_layer) {
continue;
}
@ -480,7 +480,7 @@ impl HitTester {
point_in_viewport = root_node
.world_viewport_transform
.inverse()
.and_then(|inverted| inverted.transform_point2d(&point))
.and_then(|inverted| inverted.transform_point2d(point))
.map(|pt| pt - scroll_node.external_scroll_offset);
current_root_spatial_node_index = root_spatial_node_index;
@ -562,7 +562,7 @@ impl HitTest {
return self.point;
}
let point = &LayoutPoint::new(self.point.x, self.point.y);
let point = LayoutPoint::new(self.point.x, self.point.y);
self.pipeline_id
.and_then(|id|
hit_tester

Просмотреть файл

@ -12,7 +12,7 @@ use crate::clip_scroll_tree::{ROOT_SPATIAL_NODE_INDEX,
ClipScrollTree, CoordinateSpaceMapping, SpatialNodeIndex, VisibleFace, CoordinateSystemId
};
use crate::debug_colors;
use euclid::{vec3, TypedPoint2D, TypedScale, TypedSize2D, Vector2D, TypedRect};
use euclid::{vec3, Point2D, Scale, Size2D, Vector2D, Rect};
use euclid::approxeq::ApproxEq;
use crate::filterdata::SFilterData;
use crate::frame_builder::{FrameVisibilityContext, FrameVisibilityState};
@ -139,9 +139,9 @@ impl RetainedTiles {
pub struct TileCoordinate;
// Geometry types for tile coordinates.
pub type TileOffset = TypedPoint2D<i32, TileCoordinate>;
pub type TileSize = TypedSize2D<i32, TileCoordinate>;
pub type TileRect = TypedRect<i32, TileCoordinate>;
pub type TileOffset = Point2D<i32, TileCoordinate>;
pub type TileSize = Size2D<i32, TileCoordinate>;
pub type TileRect = Rect<i32, TileCoordinate>;
/// The size in device pixels of a cached tile. The currently chosen
/// size is arbitrary. We should do some profiling to find the best
@ -1613,7 +1613,7 @@ impl PictureCompositeMode {
let inflation_factor = primitive.shadow.blur_radius.round() * BLUR_SAMPLE_SCALE;
let input = primitive.input.to_index(cur_index).map(|index| output_rects[index]).unwrap_or(picture_rect);
let shadow_rect = input.inflate(inflation_factor, inflation_factor);
input.union(&shadow_rect.translate(&(primitive.shadow.offset * TypedScale::new(1.0))))
input.union(&shadow_rect.translate(primitive.shadow.offset * Scale::new(1.0)))
}
FilterPrimitiveKind::Blend(ref primitive) => {
primitive.input1.to_index(cur_index).map(|index| output_rects[index]).unwrap_or(picture_rect)
@ -2691,7 +2691,7 @@ impl PicturePrimitive {
match transform {
CoordinateSpaceMapping::Local => {
let polygon = Polygon::from_rect(
local_rect * TypedScale::new(1.0),
local_rect * Scale::new(1.0),
plane_split_anchor,
);
splitter.add(polygon);
@ -2754,10 +2754,10 @@ impl PicturePrimitive {
};
let local_points = [
transform.transform_point3d(&poly.points[0].cast()).unwrap(),
transform.transform_point3d(&poly.points[1].cast()).unwrap(),
transform.transform_point3d(&poly.points[2].cast()).unwrap(),
transform.transform_point3d(&poly.points[3].cast()).unwrap(),
transform.transform_point3d(poly.points[0].cast()).unwrap(),
transform.transform_point3d(poly.points[1].cast()).unwrap(),
transform.transform_point3d(poly.points[2].cast()).unwrap(),
transform.transform_point3d(poly.points[3].cast()).unwrap(),
];
let gpu_blocks = [
[local_points[0].x, local_points[0].y, local_points[1].x, local_points[1].y].into(),
@ -2961,7 +2961,7 @@ impl PicturePrimitive {
// This inflaction factor is to be applied to the surface itself.
surface.rect = raster_config.composite_mode.inflate_picture_rect(surface.rect, surface.inflation_factor);
let mut surface_rect = surface.rect * TypedScale::new(1.0);
let mut surface_rect = surface.rect * Scale::new(1.0);
// Pop this surface from the stack
let surface_index = state.pop_surface();
@ -2988,7 +2988,7 @@ impl PicturePrimitive {
PictureCompositeMode::Filter(Filter::DropShadows(ref shadows)) => {
for shadow in shadows {
let content_rect = surface_rect;
let shadow_rect = surface_rect.translate(&shadow.offset);
let shadow_rect = surface_rect.translate(shadow.offset);
surface_rect = content_rect.union(&shadow_rect);
}
}
@ -3050,7 +3050,7 @@ impl PicturePrimitive {
// Basic brush primitive header is (see end of prepare_prim_for_render_inner in prim_store.rs)
// [brush specific data]
// [segment_rect, segment data]
let shadow_rect = self.snapped_local_rect.translate(&shadow.offset);
let shadow_rect = self.snapped_local_rect.translate(shadow.offset);
// ImageBrush colors
request.push(shadow.color.premultiplied());
@ -3113,7 +3113,7 @@ fn calculate_screen_uv(
device_pixel_scale: DevicePixelScale,
supports_snapping: bool,
) -> DeviceHomogeneousVector {
let raster_pos = transform.transform_point2d_homogeneous(local_pos);
let raster_pos = transform.transform_point2d_homogeneous(*local_pos);
let mut device_vec = DeviceHomogeneousVector::new(
raster_pos.x * device_pixel_scale.0,

Просмотреть файл

@ -22,7 +22,7 @@ use core_graphics::geometry::{CG_AFFINE_TRANSFORM_IDENTITY, CGRect};
use core_text;
use core_text::font::{CTFont, CTFontRef};
use core_text::font_descriptor::{kCTFontDefaultOrientation, kCTFontColorGlyphsTrait};
use euclid::Size2D;
use euclid::default::Size2D;
use crate::gamma_lut::{ColorLut, GammaLut};
use crate::glyph_rasterizer::{FontInstance, FontTransform, GlyphKey};
use crate::glyph_rasterizer::{GlyphFormat, GlyphRasterError, GlyphRasterResult, RasterizedGlyph};

Просмотреть файл

@ -16,7 +16,7 @@ use crate::clip::{ClipDataStore, ClipNodeFlags, ClipChainId, ClipChainInstance,
use crate::debug_colors;
use crate::debug_render::DebugItem;
use crate::display_list_flattener::{CreateShadow, IsVisible};
use euclid::{SideOffsets2D, TypedTransform3D, TypedRect, TypedScale, TypedSize2D, TypedPoint2D};
use euclid::{SideOffsets2D, Transform3D, Rect, Scale, Size2D, Point2D};
use euclid::approxeq::ApproxEq;
use crate::frame_builder::{FrameBuildingContext, FrameBuildingState, PictureContext, PictureState};
use crate::frame_builder::{FrameVisibilityContext, FrameVisibilityState};
@ -134,14 +134,14 @@ pub struct SpaceMapper<F, T> {
kind: CoordinateSpaceMapping<F, T>,
pub ref_spatial_node_index: SpatialNodeIndex,
pub current_target_spatial_node_index: SpatialNodeIndex,
pub bounds: TypedRect<f32, T>,
pub bounds: Rect<f32, T>,
visible_face: VisibleFace,
}
impl<F, T> SpaceMapper<F, T> where F: fmt::Debug {
pub fn new(
ref_spatial_node_index: SpatialNodeIndex,
bounds: TypedRect<f32, T>,
bounds: Rect<f32, T>,
) -> Self {
SpaceMapper {
kind: CoordinateSpaceMapping::Local,
@ -155,7 +155,7 @@ impl<F, T> SpaceMapper<F, T> where F: fmt::Debug {
pub fn new_with_target(
ref_spatial_node_index: SpatialNodeIndex,
target_node_index: SpatialNodeIndex,
bounds: TypedRect<f32, T>,
bounds: Rect<f32, T>,
clip_scroll_tree: &ClipScrollTree,
) -> Self {
let mut mapper = Self::new(ref_spatial_node_index, bounds);
@ -195,10 +195,10 @@ impl<F, T> SpaceMapper<F, T> where F: fmt::Debug {
self.current_target_spatial_node_index = target_node_index;
}
pub fn get_transform(&self) -> TypedTransform3D<f32, F, T> {
pub fn get_transform(&self) -> Transform3D<f32, F, T> {
match self.kind {
CoordinateSpaceMapping::Local => {
TypedTransform3D::identity()
Transform3D::identity()
}
CoordinateSpaceMapping::ScaleOffset(ref scale_offset) => {
scale_offset.to_transform()
@ -209,10 +209,10 @@ impl<F, T> SpaceMapper<F, T> where F: fmt::Debug {
}
}
pub fn unmap(&self, rect: &TypedRect<f32, T>) -> Option<TypedRect<f32, F>> {
pub fn unmap(&self, rect: &Rect<f32, T>) -> Option<Rect<f32, F>> {
match self.kind {
CoordinateSpaceMapping::Local => {
Some(TypedRect::from_untyped(&rect.to_untyped()))
Some(Rect::from_untyped(&rect.to_untyped()))
}
CoordinateSpaceMapping::ScaleOffset(ref scale_offset) => {
Some(scale_offset.unmap_rect(rect))
@ -223,10 +223,10 @@ impl<F, T> SpaceMapper<F, T> where F: fmt::Debug {
}
}
pub fn map(&self, rect: &TypedRect<f32, F>) -> Option<TypedRect<f32, T>> {
pub fn map(&self, rect: &Rect<f32, F>) -> Option<Rect<f32, T>> {
match self.kind {
CoordinateSpaceMapping::Local => {
Some(TypedRect::from_untyped(&rect.to_untyped()))
Some(Rect::from_untyped(&rect.to_untyped()))
}
CoordinateSpaceMapping::ScaleOffset(ref scale_offset) => {
Some(scale_offset.map_rect(rect))
@ -407,19 +407,8 @@ impl From<SideOffsetsKey> for LayoutSideOffsets {
}
}
impl From<LayoutSideOffsets> for SideOffsetsKey {
fn from(offsets: LayoutSideOffsets) -> SideOffsetsKey {
SideOffsetsKey {
top: offsets.top,
right: offsets.right,
bottom: offsets.bottom,
left: offsets.left,
}
}
}
impl From<SideOffsets2D<f32>> for SideOffsetsKey {
fn from(offsets: SideOffsets2D<f32>) -> SideOffsetsKey {
impl<U> From<SideOffsets2D<f32, U>> for SideOffsetsKey {
fn from(offsets: SideOffsets2D<f32, U>) -> SideOffsetsKey {
SideOffsetsKey {
top: offsets.top,
right: offsets.right,
@ -453,8 +442,8 @@ impl From<SizeKey> for LayoutSize {
}
}
impl<U> From<TypedSize2D<f32, U>> for SizeKey {
fn from(size: TypedSize2D<f32, U>) -> SizeKey {
impl<U> From<Size2D<f32, U>> for SizeKey {
fn from(size: Size2D<f32, U>) -> SizeKey {
SizeKey {
w: size.width,
h: size.height,
@ -1210,7 +1199,7 @@ impl ClipData {
pub struct NinePatchDescriptor {
pub width: i32,
pub height: i32,
pub slice: SideOffsets2D<i32>,
pub slice: DeviceIntSideOffsets,
pub fill: bool,
pub repeat_horizontal: RepeatMode,
pub repeat_vertical: RepeatMode,
@ -1942,7 +1931,7 @@ impl PrimitiveStore {
PictureCompositeMode::Filter(Filter::DropShadows(ref shadows)) => {
let mut rect = LayoutRect::zero();
for shadow in shadows {
rect = rect.union(&pic.snapped_local_rect.translate(&shadow.offset));
rect = rect.union(&pic.snapped_local_rect.translate(shadow.offset));
}
rect
@ -2256,7 +2245,7 @@ impl PrimitiveStore {
// Layout space for the picture is picture space from the
// perspective of its child primitives.
let pic_local_rect = surface_rect * TypedScale::new(1.0);
let pic_local_rect = surface_rect * Scale::new(1.0);
if pic.snapped_local_rect != pic_local_rect {
match raster_config.composite_mode {
PictureCompositeMode::Filter(Filter::DropShadows(..)) => {
@ -2788,7 +2777,7 @@ impl PrimitiveStore {
if let Some(cache_key) = line_dec_data.cache_key.as_ref() {
// TODO(gw): Do we ever need / want to support scales for text decorations
// based on the current transform?
let scale_factor = TypedScale::new(1.0) * device_pixel_scale;
let scale_factor = Scale::new(1.0) * device_pixel_scale;
let task_size = (LayoutSize::from_au(cache_key.size) * scale_factor).ceil().to_i32();
// Request a pre-rendered image task.
@ -3496,7 +3485,7 @@ impl<'a> GpuDataRequest<'a> {
// ensures clip-mask tasks get allocated for these
// pixel regions, even if no other clips affect them.
let prim_shadow_rect = info.prim_shadow_rect.translate(
&LayoutVector2D::new(clip_instance.local_pos.x, clip_instance.local_pos.y),
LayoutVector2D::new(clip_instance.local_pos.x, clip_instance.local_pos.y),
);
segment_builder.push_mask_region(
prim_shadow_rect,
@ -3650,7 +3639,7 @@ impl PrimitiveInstance {
frame_state.segment_builder.build(|segment| {
segments.push(
BrushSegment::new(
segment.rect.translate(&-prim_local_rect.origin.to_vector()),
segment.rect.translate(-prim_local_rect.origin.to_vector()),
segment.has_mask,
segment.edge_flags,
[0.0; 4],
@ -3820,7 +3809,7 @@ impl PrimitiveInstance {
let segment_clip_chain = frame_state
.clip_store
.build_clip_chain_instance(
segment.local_rect.translate(&LayoutVector2D::new(
segment.local_rect.translate(LayoutVector2D::new(
self.prim_origin.x,
self.prim_origin.y,
)),
@ -3966,12 +3955,12 @@ fn mix(x: f32, y: f32, a: f32) -> f32 {
/// Given a point within a local rectangle, and the device space corners
/// of a snapped primitive, return the snap offsets.
fn compute_snap_offset_impl<PixelSpace>(
reference_pos: TypedPoint2D<f32, PixelSpace>,
reference_rect: TypedRect<f32, PixelSpace>,
reference_pos: Point2D<f32, PixelSpace>,
reference_rect: Rect<f32, PixelSpace>,
prim_top_left: DevicePoint,
prim_bottom_right: DevicePoint,
) -> DeviceVector2D {
let normalized_snap_pos = TypedPoint2D::<f32, PixelSpace>::new(
let normalized_snap_pos = Point2D::<f32, PixelSpace>::new(
(reference_pos.x - reference_rect.origin.x) / reference_rect.size.width,
(reference_pos.y - reference_rect.origin.y) / reference_rect.size.height,
);
@ -3997,8 +3986,8 @@ fn compute_snap_offset_impl<PixelSpace>(
/// This *must* exactly match the logic in the GLSL
/// compute_snap_offset function.
pub fn recompute_snap_offsets<PixelSpace>(
local_rect: TypedRect<f32, PixelSpace>,
prim_rect: TypedRect<f32, PixelSpace>,
local_rect: Rect<f32, PixelSpace>,
prim_rect: Rect<f32, PixelSpace>,
snap_offsets: SnapOffsets,
) -> SnapOffsets
{
@ -4006,12 +3995,12 @@ pub fn recompute_snap_offsets<PixelSpace>(
return SnapOffsets::empty();
}
let normalized_top_left = TypedPoint2D::<f32, PixelSpace>::new(
let normalized_top_left = Point2D::<f32, PixelSpace>::new(
(local_rect.origin.x - prim_rect.origin.x) / prim_rect.size.width,
(local_rect.origin.y - prim_rect.origin.y) / prim_rect.size.height,
);
let normalized_bottom_right = TypedPoint2D::<f32, PixelSpace>::new(
let normalized_bottom_right = Point2D::<f32, PixelSpace>::new(
(local_rect.origin.x + local_rect.size.width - prim_rect.origin.x) / prim_rect.size.width,
(local_rect.origin.y + local_rect.size.height - prim_rect.origin.y) / prim_rect.size.height,
);
@ -4039,7 +4028,7 @@ fn get_unclipped_device_rect(
device_pixel_scale: DevicePixelScale,
) -> Option<DeviceRect> {
let raster_rect = map_to_raster.map(&prim_rect)?;
let world_rect = raster_rect * TypedScale::new(1.0);
let world_rect = raster_rect * Scale::new(1.0);
Some(world_rect * device_pixel_scale)
}
@ -4056,9 +4045,9 @@ fn get_clipped_device_rect(
device_pixel_scale: DevicePixelScale,
) -> Option<(DeviceIntRect, SnapOffsets)> {
let unclipped_raster_rect = {
let world_rect = *unclipped * TypedScale::new(1.0);
let world_rect = *unclipped * Scale::new(1.0);
let raster_rect = world_rect * device_pixel_scale.inv();
TypedRect::from_untyped(&raster_rect.to_untyped())
Rect::from_untyped(&raster_rect.to_untyped())
};
let unclipped_world_rect = map_to_world.map(&unclipped_raster_rect)?;
@ -4142,10 +4131,10 @@ pub fn get_raster_rects(
/// axis-aligned. It return the snapped rect transformed back into the
/// given pixel space, and the snap offsets in device space.
pub fn get_snapped_rect<PixelSpace>(
prim_rect: TypedRect<f32, PixelSpace>,
prim_rect: Rect<f32, PixelSpace>,
map_to_raster: &SpaceMapper<PixelSpace, RasterPixel>,
device_pixel_scale: DevicePixelScale,
) -> Option<(TypedRect<f32, PixelSpace>, SnapOffsets)> where PixelSpace: fmt::Debug {
) -> Option<(Rect<f32, PixelSpace>, SnapOffsets)> where PixelSpace: fmt::Debug {
let is_axis_aligned = match map_to_raster.kind {
CoordinateSpaceMapping::Local |
CoordinateSpaceMapping::ScaleOffset(..) => true,
@ -4156,7 +4145,7 @@ pub fn get_snapped_rect<PixelSpace>(
let raster_rect = map_to_raster.map(&prim_rect)?;
let device_rect = {
let world_rect = raster_rect * TypedScale::new(1.0);
let world_rect = raster_rect * Scale::new(1.0);
world_rect * device_pixel_scale
};
@ -4185,7 +4174,7 @@ pub fn get_snapped_rect<PixelSpace>(
);
let snapped_world_rect = snapped_device_rect / device_pixel_scale;
let snapped_raster_rect = snapped_world_rect * TypedScale::new(1.0);
let snapped_raster_rect = snapped_world_rect * Scale::new(1.0);
let snapped_prim_rect = map_to_raster.unmap(&snapped_raster_rect)?;
Some((snapped_prim_rect, snap_offsets))
} else {

Просмотреть файл

@ -323,7 +323,7 @@ impl TextRunPrimitive {
glyphs.iter().map(|src| {
let src_point = src.point + prim_offset;
let world_offset = self.used_font.transform.transform(&src_point);
let device_offset = device_pixel_scale.transform_point(&world_offset);
let device_offset = device_pixel_scale.transform_point(world_offset);
GlyphKey::new(src.index, device_offset, subpx_dir)
}));
}

Просмотреть файл

@ -5,7 +5,7 @@
use api::{ColorF, ColorU};
use crate::debug_render::DebugRenderer;
use crate::device::query::{GpuSampler, GpuTimer, NamedTag};
use euclid::{Point2D, Rect, Size2D, vec2};
use euclid::{Point2D, Rect, Size2D, vec2, default};
use crate::internal_types::FastHashMap;
use crate::renderer::{MAX_VERTEX_TEXTURE_WIDTH, wr_has_been_initialized};
use std::collections::vec_deque::VecDeque;
@ -687,7 +687,7 @@ impl ProfileGraph {
y: f32,
description: &'static str,
debug_renderer: &mut DebugRenderer,
) -> Rect<f32> {
) -> default::Rect<f32> {
let size = Size2D::new(600.0, 120.0);
let line_height = debug_renderer.line_height();
let graph_rect = Rect::new(Point2D::new(x, y), size);
@ -812,7 +812,7 @@ impl GpuFrameCollection {
}
impl GpuFrameCollection {
fn draw(&self, x: f32, y: f32, debug_renderer: &mut DebugRenderer) -> Rect<f32> {
fn draw(&self, x: f32, y: f32, debug_renderer: &mut DebugRenderer) -> default::Rect<f32> {
let graph_rect = Rect::new(
Point2D::new(x, y),
Size2D::new(GRAPH_WIDTH, GRAPH_HEIGHT),
@ -1019,7 +1019,7 @@ impl Profiler {
label_color: ColorU,
counters: &[(ColorU, &IntProfileCounter)],
debug_renderer: &mut DebugRenderer,
) -> Rect<f32> {
) -> default::Rect<f32> {
let mut rect = debug_renderer.add_text(
self.draw_state.x_left,
self.draw_state.y_left,

Просмотреть файл

@ -1723,8 +1723,8 @@ impl RenderTask {
};
if let Some(mut request) = gpu_cache.request(cache_handle) {
let p0 = target_rect.origin.to_f32();
let p1 = target_rect.bottom_right().to_f32();
let p0 = target_rect.min().to_f32();
let p1 = target_rect.max().to_f32();
let image_source = ImageSource {
p0,
p1,

Просмотреть файл

@ -55,7 +55,7 @@ use crate::device::{ShaderError, TextureFilter, TextureFlags,
VertexUsageHint, VAO, VBO, CustomVAO};
use crate::device::{ProgramCache};
use crate::device::query::GpuTimer;
use euclid::{rect, Transform3D, TypedScale};
use euclid::{rect, Transform3D, Scale, default};
use crate::frame_builder::{ChasePrimitive, FrameBuilderConfig};
use gleam::gl;
use crate::glyph_cache::GlyphCache;
@ -3321,7 +3321,7 @@ impl Renderer {
readback_rect.size,
);
let mut dest = readback_rect.to_i32();
let device_to_framebuffer = TypedScale::new(1i32);
let device_to_framebuffer = Scale::new(1i32);
// Need to invert the y coordinates and flip the image vertically when
// reading back from the framebuffer.
@ -3397,7 +3397,7 @@ impl Renderer {
read_target.into(),
read_target.to_framebuffer_rect(source_rect),
draw_target,
draw_target.to_framebuffer_rect(blit.target_rect.translate(&-content_origin.to_vector())),
draw_target.to_framebuffer_rect(blit.target_rect.translate(-content_origin.to_vector())),
TextureFilter::Linear,
);
}
@ -3407,7 +3407,7 @@ impl Renderer {
&mut self,
scalings: &[ScalingInstance],
source: TextureSource,
projection: &Transform3D<f32>,
projection: &default::Transform3D<f32>,
stats: &mut RendererStats,
) {
if scalings.is_empty() {
@ -3437,7 +3437,7 @@ impl Renderer {
&mut self,
textures: &BatchTextures,
svg_filters: &[SvgFilterInstance],
projection: &Transform3D<f32>,
projection: &default::Transform3D<f32>,
stats: &mut RendererStats,
) {
if svg_filters.is_empty() {
@ -3465,7 +3465,7 @@ impl Renderer {
target: &PictureCacheTarget,
draw_target: DrawTarget,
content_origin: DeviceIntPoint,
projection: &Transform3D<f32>,
projection: &default::Transform3D<f32>,
render_tasks: &RenderTaskGraph,
stats: &mut RendererStats,
) {
@ -3508,7 +3508,7 @@ impl Renderer {
draw_target: DrawTarget,
content_origin: DeviceIntPoint,
framebuffer_kind: FramebufferKind,
projection: &Transform3D<f32>,
projection: &default::Transform3D<f32>,
render_tasks: &RenderTaskGraph,
stats: &mut RendererStats,
) {
@ -3718,7 +3718,7 @@ impl Renderer {
clear_color: Option<[f32; 4]>,
clear_depth: Option<f32>,
render_tasks: &RenderTaskGraph,
projection: &Transform3D<f32>,
projection: &default::Transform3D<f32>,
frame_id: GpuFrameId,
stats: &mut RendererStats,
) {
@ -3874,7 +3874,7 @@ impl Renderer {
let (src_rect, _) = render_tasks[output.task_id].get_target_rect();
self.device.blit_render_target_invert_y(
draw_target.into(),
draw_target.to_framebuffer_rect(src_rect.translate(&-content_origin.to_vector())),
draw_target.to_framebuffer_rect(src_rect.translate(-content_origin.to_vector())),
DrawTarget::External { fbo: fbo_id, size: output_size },
output_size.into(),
);
@ -3887,7 +3887,7 @@ impl Renderer {
fn draw_clip_batch_list(
&mut self,
list: &ClipBatchList,
projection: &Transform3D<f32>,
projection: &default::Transform3D<f32>,
stats: &mut RendererStats,
) {
if self.debug_flags.contains(DebugFlags::DISABLE_CLIP_MASKS) {
@ -3968,7 +3968,7 @@ impl Renderer {
&mut self,
draw_target: DrawTarget,
target: &AlphaRenderTarget,
projection: &Transform3D<f32>,
projection: &default::Transform3D<f32>,
render_tasks: &RenderTaskGraph,
stats: &mut RendererStats,
) {
@ -4508,7 +4508,7 @@ impl Renderer {
ORTHO_FAR_PLANE,
);
let fb_scale = TypedScale::<_, _, FramebufferPixel>::new(1i32);
let fb_scale = Scale::<_, _, FramebufferPixel>::new(1i32);
let mut fb_rect = frame.device_rect * fb_scale;
fb_rect.origin.y = device_size.height - fb_rect.origin.y - fb_rect.size.height;
@ -4695,7 +4695,7 @@ impl Renderer {
pub fn init_pixel_local_storage(
&mut self,
task_rect: DeviceIntRect,
projection: &Transform3D<f32>,
projection: &default::Transform3D<f32>,
stats: &mut RendererStats,
) {
self.device.enable_pixel_local_storage(true);
@ -4725,7 +4725,7 @@ impl Renderer {
pub fn resolve_pixel_local_storage(
&mut self,
task_rect: DeviceIntRect,
projection: &Transform3D<f32>,
projection: &default::Transform3D<f32>,
stats: &mut RendererStats,
) {
self.shaders
@ -4888,7 +4888,7 @@ impl Renderer {
let texture_rect = FramebufferIntRect::new(
FramebufferIntPoint::zero(),
FramebufferIntSize::from_untyped(&source_rect.size.to_untyped()),
FramebufferIntSize::from_untyped(source_rect.size.to_untyped()),
);
debug_renderer.add_rect(
@ -5145,7 +5145,7 @@ impl Renderer {
pub fn read_gpu_cache(&mut self) -> (DeviceIntSize, Vec<u8>) {
let texture = self.gpu_cache_texture.texture.as_ref().unwrap();
let size = FramebufferIntSize::from_untyped(&texture.get_dimensions().to_untyped());
let size = FramebufferIntSize::from_untyped(texture.get_dimensions().to_untyped());
let mut texels = vec![0; (size.width * size.height * 16) as usize];
self.device.begin_frame();
self.device.bind_read_target(ReadTarget::from_texture(texture, 0));
@ -5666,7 +5666,7 @@ impl Renderer {
// read from textures directly with `get_tex_image*`.
for layer_id in 0 .. texture.get_layer_count() {
let rect = FramebufferIntSize::from_untyped(&rect_size.to_untyped()).into();
let rect = FramebufferIntSize::from_untyped(rect_size.to_untyped()).into();
device.attach_read_texture(texture, layer_id);
#[cfg(feature = "png")]

Просмотреть файл

@ -718,16 +718,16 @@ impl ResourceCache {
};
tiles.retain(|tile, _| {
!req.original_tile_range.contains(tile) ||
req.actual_tile_range.contains(tile)
!req.original_tile_range.contains(*tile) ||
req.actual_tile_range.contains(*tile)
});
let texture_cache = &mut self.texture_cache;
match self.cached_images.try_get_mut(&req.key.as_image()) {
Some(&mut ImageResult::Multi(ref mut entries)) => {
entries.retain(|key, entry| {
if !req.original_tile_range.contains(&key.tile.unwrap()) ||
req.actual_tile_range.contains(&key.tile.unwrap()) {
if !req.original_tile_range.contains(key.tile.unwrap()) ||
req.actual_tile_range.contains(key.tile.unwrap()) {
return true;
}
entry.mark_unused(texture_cache);
@ -1386,13 +1386,13 @@ impl ResourceCache {
tile_size,
);
tiles.retain(|tile, _| { tile_range.contains(tile) });
tiles.retain(|tile, _| { tile_range.contains(*tile) });
let texture_cache = &mut self.texture_cache;
match self.cached_images.try_get_mut(&key.as_image()) {
Some(&mut ImageResult::Multi(ref mut entries)) => {
entries.retain(|key, entry| {
if key.tile.is_none() || tile_range.contains(&key.tile.unwrap()) {
if key.tile.is_none() || tile_range.contains(key.tile.unwrap()) {
return true;
}
entry.mark_unused(texture_cache);

Просмотреть файл

@ -4,7 +4,7 @@
use crate::batch::{BatchKey, BatchKind, BrushBatchKind, BatchFeatures};
use crate::device::{Device, Program, ShaderError};
use euclid::{Transform3D};
use euclid::default::Transform3D;
use crate::glyph_rasterizer::GlyphFormat;
use crate::renderer::{
desc,

Просмотреть файл

@ -309,8 +309,8 @@ impl SpatialNode {
// Do a change-basis operation on the
// perspective matrix using the scroll offset.
source_transform
.pre_translate(&scroll_offset)
.post_translate(&-scroll_offset)
.pre_translate(scroll_offset)
.post_translate(-scroll_offset)
}
ReferenceFrameKind::Perspective { scrolling_relative_to: None } |
ReferenceFrameKind::Transform => source_transform,
@ -318,14 +318,14 @@ impl SpatialNode {
let resolved_transform =
LayoutFastTransform::with_vector(info.origin_in_parent_reference_frame)
.pre_mul(&source_transform);
.pre_transform(&source_transform);
// The transformation for this viewport in world coordinates is the transformation for
// our parent reference frame, plus any accumulated scrolling offsets from nodes
// between our reference frame and this node. Finally, we also include
// whatever local transformation this reference frame provides.
let relative_transform = resolved_transform
.post_translate(&state.parent_accumulated_scroll_offset)
.post_translate(state.parent_accumulated_scroll_offset)
.to_transform()
.with_destination::<LayoutPixel>();
@ -352,7 +352,7 @@ impl SpatialNode {
// new incompatible coordinate system with which we cannot share clips without masking.
let transform = state.coordinate_system_relative_scale_offset
.to_transform()
.pre_mul(&relative_transform);
.pre_transform(&relative_transform);
// Push that new coordinate system and record the new id.
let coord_system = {
@ -361,7 +361,7 @@ impl SpatialNode {
if parent_system.should_flatten {
cur_transform.flatten_z_output();
}
let world_transform = cur_transform.post_mul(&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();
@ -437,7 +437,7 @@ impl SpatialNode {
// between the scrolled content and unscrolled viewport we adjust the viewport's
// position by the scroll offset in order to work with their relative positions on the
// page.
let sticky_rect = info.frame_rect.translate(viewport_scroll_offset);
let sticky_rect = info.frame_rect.translate(*viewport_scroll_offset);
let mut sticky_offset = LayoutVector2D::zero();
if let Some(margin) = info.margins.top {
@ -560,7 +560,7 @@ impl SpatialNode {
let translation = -info.origin_in_parent_reference_frame;
state.nearest_scrolling_ancestor_viewport =
state.nearest_scrolling_ancestor_viewport
.translate(&translation);
.translate(translation);
}
}
}
@ -763,7 +763,7 @@ pub struct ReferenceFrameInfo {
#[derive(Clone, Debug)]
pub struct StickyFrameInfo {
pub frame_rect: LayoutRect,
pub margins: SideOffsets2D<Option<f32>>,
pub margins: SideOffsets2D<Option<f32>, LayoutPixel>,
pub vertical_offset_bounds: StickyOffsetBounds,
pub horizontal_offset_bounds: StickyOffsetBounds,
pub previously_applied_offset: LayoutVector2D,
@ -773,7 +773,7 @@ pub struct StickyFrameInfo {
impl StickyFrameInfo {
pub fn new(
frame_rect: LayoutRect,
margins: SideOffsets2D<Option<f32>>,
margins: SideOffsets2D<Option<f32>, LayoutPixel>,
vertical_offset_bounds: StickyOffsetBounds,
horizontal_offset_bounds: StickyOffsetBounds,
previously_applied_offset: LayoutVector2D

Просмотреть файл

@ -4,8 +4,8 @@
use api::BorderRadius;
use api::units::*;
use euclid::{TypedPoint2D, TypedRect, TypedSize2D, Vector2D};
use euclid::{TypedTransform2D, TypedTransform3D, TypedVector2D, TypedScale};
use euclid::{Point2D, Rect, Size2D, Vector2D};
use euclid::{default, Transform2D, Transform3D, Scale};
use malloc_size_of::{MallocShallowSizeOf, MallocSizeOf, MallocSizeOfOps};
use plane_split::{Clipper, Polygon};
use std::{i32, f32, fmt, ptr};
@ -119,8 +119,8 @@ impl<T> VecHelper<T> for Vec<T> {
#[derive(Debug, Clone, Copy, MallocSizeOf)]
#[cfg_attr(feature = "capture", derive(Serialize))]
pub struct ScaleOffset {
pub scale: Vector2D<f32>,
pub offset: Vector2D<f32>,
pub scale: default::Vector2D<f32>,
pub offset: default::Vector2D<f32>,
}
impl ScaleOffset {
@ -134,7 +134,7 @@ impl ScaleOffset {
// Construct a ScaleOffset from a transform. Returns
// None if the matrix is not a pure scale / translation.
pub fn from_transform<F, T>(
m: &TypedTransform3D<f32, F, T>,
m: &Transform3D<f32, F, T>,
) -> Option<ScaleOffset> {
// To check that we have a pure scale / translation:
@ -178,7 +178,7 @@ impl ScaleOffset {
}
}
pub fn offset(&self, offset: Vector2D<f32>) -> Self {
pub fn offset(&self, offset: default::Vector2D<f32>) -> Self {
self.accumulate(
&ScaleOffset {
scale: Vector2D::new(1.0, 1.0),
@ -189,7 +189,7 @@ impl ScaleOffset {
/// Produce a ScaleOffset that includes both self and other.
/// The 'self' ScaleOffset is applied after other.
/// This is equivalent to `TypedTransform3D::pre_mul`.
/// This is equivalent to `Transform3D::pre_transform`.
pub fn accumulate(&self, other: &ScaleOffset) -> Self {
ScaleOffset {
scale: Vector2D::new(
@ -203,34 +203,34 @@ impl ScaleOffset {
}
}
pub fn map_rect<F, T>(&self, rect: &TypedRect<f32, F>) -> TypedRect<f32, T> {
TypedRect::new(
TypedPoint2D::new(
pub fn map_rect<F, T>(&self, rect: &Rect<f32, F>) -> Rect<f32, T> {
Rect::new(
Point2D::new(
rect.origin.x * self.scale.x + self.offset.x,
rect.origin.y * self.scale.y + self.offset.y,
),
TypedSize2D::new(
Size2D::new(
rect.size.width * self.scale.x,
rect.size.height * self.scale.y,
)
)
}
pub fn unmap_rect<F, T>(&self, rect: &TypedRect<f32, F>) -> TypedRect<f32, T> {
TypedRect::new(
TypedPoint2D::new(
pub fn unmap_rect<F, T>(&self, rect: &Rect<f32, F>) -> Rect<f32, T> {
Rect::new(
Point2D::new(
(rect.origin.x - self.offset.x) / self.scale.x,
(rect.origin.y - self.offset.y) / self.scale.y,
),
TypedSize2D::new(
Size2D::new(
rect.size.width / self.scale.x,
rect.size.height / self.scale.y,
)
)
}
pub fn to_transform<F, T>(&self) -> TypedTransform3D<f32, F, T> {
TypedTransform3D::row_major(
pub fn to_transform<F, T>(&self) -> Transform3D<f32, F, T> {
Transform3D::row_major(
self.scale.x,
0.0,
0.0,
@ -264,8 +264,8 @@ pub trait MatrixHelpers<Src, Dst> {
/// Check if the matrix post-scaling on either the X or Y axes could cause geometry
/// transformed by this matrix to have scaling exceeding the supplied limit.
fn exceeds_2d_scale(&self, limit: f64) -> bool;
fn inverse_project(&self, target: &TypedPoint2D<f32, Dst>) -> Option<TypedPoint2D<f32, Src>>;
fn inverse_rect_footprint(&self, rect: &TypedRect<f32, Dst>) -> Option<TypedRect<f32, Src>>;
fn inverse_project(&self, target: &Point2D<f32, Dst>) -> Option<Point2D<f32, Src>>;
fn inverse_rect_footprint(&self, rect: &Rect<f32, Dst>) -> Option<Rect<f32, Src>>;
fn transform_kind(&self) -> TransformedRectKind;
fn is_simple_translation(&self) -> bool;
fn is_simple_2d_translation(&self) -> bool;
@ -274,13 +274,13 @@ pub trait MatrixHelpers<Src, Dst> {
/// This function returns a point in the `Src` space that projects into zero XY.
/// It ignores the Z coordinate and is usable for "flattened" transformations,
/// since they are not generally inversible.
fn inverse_project_2d_origin(&self) -> Option<TypedPoint2D<f32, Src>>;
fn inverse_project_2d_origin(&self) -> Option<Point2D<f32, Src>>;
/// Turn Z transformation into identity. This is useful when crossing "flat"
/// transform styled stacking contexts upon traversing the coordinate systems.
fn flatten_z_output(&mut self);
}
impl<Src, Dst> MatrixHelpers<Src, Dst> for TypedTransform3D<f32, Src, Dst> {
impl<Src, Dst> MatrixHelpers<Src, Dst> for Transform3D<f32, Src, Dst> {
fn preserves_2d_axis_alignment(&self) -> bool {
if self.m14 != 0.0 || self.m24 != 0.0 {
return false;
@ -328,9 +328,9 @@ impl<Src, Dst> MatrixHelpers<Src, Dst> for TypedTransform3D<f32, Src, Dst> {
self.m21 * self.m21 + self.m22 * self.m22 > limit2
}
fn inverse_project(&self, target: &TypedPoint2D<f32, Dst>) -> Option<TypedPoint2D<f32, Src>> {
let m: TypedTransform2D<f32, Src, Dst>;
m = TypedTransform2D::column_major(
fn inverse_project(&self, target: &Point2D<f32, Dst>) -> Option<Point2D<f32, Src>> {
let m: Transform2D<f32, Src, Dst>;
m = Transform2D::column_major(
self.m11 - target.x * self.m14,
self.m21 - target.x * self.m24,
self.m41 - target.x * self.m44,
@ -338,11 +338,11 @@ impl<Src, Dst> MatrixHelpers<Src, Dst> for TypedTransform3D<f32, Src, Dst> {
self.m22 - target.y * self.m24,
self.m42 - target.y * self.m44,
);
m.inverse().map(|inv| TypedPoint2D::new(inv.m31, inv.m32))
m.inverse().map(|inv| Point2D::new(inv.m31, inv.m32))
}
fn inverse_rect_footprint(&self, rect: &TypedRect<f32, Dst>) -> Option<TypedRect<f32, Src>> {
Some(TypedRect::from_points(&[
fn inverse_rect_footprint(&self, rect: &Rect<f32, Dst>) -> Option<Rect<f32, Src>> {
Some(Rect::from_points(&[
self.inverse_project(&rect.origin)?,
self.inverse_project(&rect.top_right())?,
self.inverse_project(&rect.bottom_left())?,
@ -385,12 +385,12 @@ impl<Src, Dst> MatrixHelpers<Src, Dst> for TypedTransform3D<f32, Src, Dst> {
self.m11 * self.m22 - self.m12 * self.m21
}
fn inverse_project_2d_origin(&self) -> Option<TypedPoint2D<f32, Src>> {
fn inverse_project_2d_origin(&self) -> Option<Point2D<f32, Src>> {
let det = self.determinant_2d();
if det != 0.0 {
let x = (self.m21 * self.m42 - self.m41 * self.m22) / det;
let y = (self.m12 * self.m41 - self.m11 * self.m42) / det;
Some(TypedPoint2D::new(x, y))
Some(Point2D::new(x, y))
} else {
None
}
@ -412,11 +412,11 @@ where
fn is_well_formed_and_nonempty(&self) -> bool;
}
impl<U> RectHelpers<U> for TypedRect<f32, U> {
impl<U> RectHelpers<U> for Rect<f32, U> {
fn from_floats(x0: f32, y0: f32, x1: f32, y1: f32) -> Self {
TypedRect::new(
TypedPoint2D::new(x0, y0),
TypedSize2D::new(x1 - x0, y1 - y0),
Rect::new(
Point2D::new(x0, y0),
Size2D::new(x1 - x0, y1 - y0),
)
}
@ -445,10 +445,10 @@ pub fn pack_as_float(value: u32) -> f32 {
#[inline]
fn extract_inner_rect_impl<U>(
rect: &TypedRect<f32, U>,
rect: &Rect<f32, U>,
radii: &BorderRadius,
k: f32,
) -> Option<TypedRect<f32, U>> {
) -> Option<Rect<f32, U>> {
// `k` defines how much border is taken into account
// We enforce the offsets to be rounded to pixel boundaries
// by `ceil`-ing and `floor`-ing them
@ -460,9 +460,9 @@ fn extract_inner_rect_impl<U>(
(rect.size.height - k * radii.bottom_left.height.max(radii.bottom_right.height)).floor();
if xl <= xr && yt <= yb {
Some(TypedRect::new(
TypedPoint2D::new(rect.origin.x + xl, rect.origin.y + yt),
TypedSize2D::new(xr - xl, yb - yt),
Some(Rect::new(
Point2D::new(rect.origin.x + xl, rect.origin.y + yt),
Size2D::new(xr - xl, yb - yt),
))
} else {
None
@ -472,9 +472,9 @@ fn extract_inner_rect_impl<U>(
/// Return an aligned rectangle that is inside the clip region and doesn't intersect
/// any of the bounding rectangles of the rounded corners.
pub fn extract_inner_rect_safe<U>(
rect: &TypedRect<f32, U>,
rect: &Rect<f32, U>,
radii: &BorderRadius,
) -> Option<TypedRect<f32, U>> {
) -> Option<Rect<f32, U>> {
// value of `k==1.0` is used for extraction of the corner rectangles
// see `SEGMENT_CORNER_*` in `clip_shared.glsl`
extract_inner_rect_impl(rect, radii, 1.0)
@ -483,7 +483,8 @@ pub fn extract_inner_rect_safe<U>(
#[cfg(test)]
pub mod test {
use super::*;
use euclid::{Point2D, Angle, Transform3D};
use euclid::default::{Point2D, Transform3D};
use euclid::Angle;
use std::f32::consts::PI;
#[test]
@ -516,7 +517,7 @@ pub mod test {
validate_convert(&xref);
let xref = LayoutTransform::create_translation(50.0, 240.0, 0.0)
.pre_mul(&LayoutTransform::create_scale(30.0, 11.0, 1.0));
.pre_transform(&LayoutTransform::create_scale(30.0, 11.0, 1.0));
validate_convert(&xref);
}
@ -544,12 +545,12 @@ pub mod test {
validate_inverse(&xref);
let xref = LayoutTransform::create_translation(50.0, 240.0, 0.0)
.pre_mul(&LayoutTransform::create_scale(30.0, 11.0, 1.0));
.pre_transform(&LayoutTransform::create_scale(30.0, 11.0, 1.0));
validate_inverse(&xref);
}
fn validate_accumulate(x0: &LayoutTransform, x1: &LayoutTransform) {
let x = x0.pre_mul(x1);
let x = x0.pre_transform(x1);
let s0 = ScaleOffset::from_transform(x0).unwrap();
let s1 = ScaleOffset::from_transform(x1).unwrap();
@ -580,7 +581,7 @@ pub mod test {
m.m42 = 0.5;
let origin = m.inverse_project_2d_origin().unwrap();
assert_eq!(origin, Point2D::new(1.0, 0.5));
assert_eq!(m.transform_point2d(&origin), Some(Point2D::zero()));
assert_eq!(m.transform_point2d(origin), Some(Point2D::zero()));
}
}
@ -597,7 +598,7 @@ impl MaxRect for DeviceIntRect {
}
}
impl<U> MaxRect for TypedRect<f32, U> {
impl<U> MaxRect for Rect<f32, U> {
fn max_rect() -> Self {
// Having an unlimited bounding box is fine up until we try
// to cast it to `i32`, where we get `-2147483648` for any
@ -607,9 +608,9 @@ impl<U> MaxRect for TypedRect<f32, U> {
// with explanation left as an exercise for the reader.
const MAX_COORD: f32 = 1.0e9;
TypedRect::new(
TypedPoint2D::new(-MAX_COORD, -MAX_COORD),
TypedSize2D::new(2.0 * MAX_COORD, 2.0 * MAX_COORD),
Rect::new(
Point2D::new(-MAX_COORD, -MAX_COORD),
Size2D::new(2.0 * MAX_COORD, 2.0 * MAX_COORD),
)
}
}
@ -619,12 +620,12 @@ impl<U> MaxRect for TypedRect<f32, U> {
#[derive(Debug, MallocSizeOf)]
pub enum FastTransform<Src, Dst> {
/// A simple offset, which can be used without doing any matrix math.
Offset(TypedVector2D<f32, Src>),
Offset(Vector2D<f32, Src>),
/// A 2D transformation with an inverse.
Transform {
transform: TypedTransform3D<f32, Src, Dst>,
inverse: Option<TypedTransform3D<f32, Dst, Src>>,
transform: Transform3D<f32, Src, Dst>,
inverse: Option<Transform3D<f32, Dst, Src>>,
is_2d: bool,
},
}
@ -639,16 +640,16 @@ impl<Src, Dst> Copy for FastTransform<Src, Dst> { }
impl<Src, Dst> FastTransform<Src, Dst> {
pub fn identity() -> Self {
FastTransform::Offset(TypedVector2D::zero())
FastTransform::Offset(Vector2D::zero())
}
pub fn with_vector(offset: TypedVector2D<f32, Src>) -> Self {
pub fn with_vector(offset: Vector2D<f32, Src>) -> Self {
FastTransform::Offset(offset)
}
pub fn with_scale_offset(scale_offset: ScaleOffset) -> Self {
if scale_offset.scale == Vector2D::new(1.0, 1.0) {
FastTransform::Offset(TypedVector2D::from_untyped(&scale_offset.offset))
FastTransform::Offset(Vector2D::from_untyped(scale_offset.offset))
} else {
FastTransform::Transform {
transform: scale_offset.to_transform(),
@ -659,19 +660,19 @@ impl<Src, Dst> FastTransform<Src, Dst> {
}
#[inline(always)]
pub fn with_transform(transform: TypedTransform3D<f32, Src, Dst>) -> Self {
pub fn with_transform(transform: Transform3D<f32, Src, Dst>) -> Self {
if transform.is_simple_2d_translation() {
return FastTransform::Offset(TypedVector2D::new(transform.m41, transform.m42));
return FastTransform::Offset(Vector2D::new(transform.m41, transform.m42));
}
let inverse = transform.inverse();
let is_2d = transform.is_2d();
FastTransform::Transform { transform, inverse, is_2d}
}
pub fn to_transform(&self) -> Cow<TypedTransform3D<f32, Src, Dst>> {
pub fn to_transform(&self) -> Cow<Transform3D<f32, Src, Dst>> {
match *self {
FastTransform::Offset(offset) => Cow::Owned(
TypedTransform3D::create_translation(offset.x, offset.y, 0.0)
Transform3D::create_translation(offset.x, offset.y, 0.0)
),
FastTransform::Transform { ref transform, .. } => Cow::Borrowed(transform),
}
@ -682,19 +683,19 @@ impl<Src, Dst> FastTransform<Src, Dst> {
pub fn is_identity(&self)-> bool {
match *self {
FastTransform::Offset(offset) => {
offset == TypedVector2D::zero()
offset == Vector2D::zero()
}
FastTransform::Transform { ref transform, .. } => {
*transform == TypedTransform3D::identity()
*transform == Transform3D::identity()
}
}
}
pub fn post_mul<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) => {
FastTransform::Offset(offset + other_offset * TypedScale::<_, _, Src>::new(1.0))
FastTransform::Offset(offset + other_offset * Scale::<_, _, Src>::new(1.0))
}
FastTransform::Transform { transform: ref other_transform, .. } => {
FastTransform::with_transform(
@ -714,9 +715,9 @@ impl<Src, Dst> FastTransform<Src, Dst> {
}
FastTransform::Transform { transform: ref other_transform, inverse: ref other_inverse, is_2d: other_is_2d } => {
FastTransform::Transform {
transform: transform.post_mul(other_transform),
transform: transform.post_transform(other_transform),
inverse: inverse.as_ref().and_then(|self_inv|
other_inverse.as_ref().map(|other_inv| self_inv.pre_mul(other_inv))
other_inverse.as_ref().map(|other_inv| self_inv.pre_transform(other_inv))
),
is_2d: is_2d & other_is_2d,
}
@ -725,26 +726,26 @@ impl<Src, Dst> FastTransform<Src, Dst> {
}
}
pub fn pre_mul<NewSrc>(
pub fn pre_transform<NewSrc>(
&self,
other: &FastTransform<NewSrc, Src>
) -> FastTransform<NewSrc, Dst> {
other.post_mul(self)
other.post_transform(self)
}
pub fn pre_translate(&self, other_offset: &TypedVector2D<f32, Src>) -> Self {
pub fn pre_translate(&self, other_offset: Vector2D<f32, Src>) -> Self {
match *self {
FastTransform::Offset(ref offset) =>
FastTransform::Offset(*offset + *other_offset),
FastTransform::Offset(offset) =>
FastTransform::Offset(offset + other_offset),
FastTransform::Transform { transform, .. } =>
FastTransform::with_transform(transform.pre_translate(other_offset.to_3d()))
}
}
pub fn post_translate(&self, other_offset: &TypedVector2D<f32, Dst>) -> Self {
pub fn post_translate(&self, other_offset: Vector2D<f32, Dst>) -> Self {
match *self {
FastTransform::Offset(ref offset) => {
FastTransform::Offset(*offset + *other_offset * TypedScale::<_, _, Src>::new(1.0))
FastTransform::Offset(offset) => {
FastTransform::Offset(offset + other_offset * Scale::<_, _, Src>::new(1.0))
}
FastTransform::Transform { ref transform, .. } => {
let transform = transform.post_translate(other_offset.to_3d());
@ -765,11 +766,11 @@ impl<Src, Dst> FastTransform<Src, Dst> {
}
#[inline(always)]
pub fn transform_point2d(&self, point: &TypedPoint2D<f32, Src>) -> Option<TypedPoint2D<f32, Dst>> {
pub fn transform_point2d(&self, point: Point2D<f32, Src>) -> Option<Point2D<f32, Dst>> {
match *self {
FastTransform::Offset(offset) => {
let new_point = *point + offset;
Some(TypedPoint2D::from_untyped(&new_point.to_untyped()))
let new_point = point + offset;
Some(Point2D::from_untyped(new_point.to_untyped()))
}
FastTransform::Transform { ref transform, .. } => transform.transform_point2d(point),
}
@ -779,7 +780,7 @@ impl<Src, Dst> FastTransform<Src, Dst> {
pub fn inverse(&self) -> Option<FastTransform<Dst, Src>> {
match *self {
FastTransform::Offset(offset) =>
Some(FastTransform::Offset(TypedVector2D::new(-offset.x, -offset.y))),
Some(FastTransform::Offset(Vector2D::new(-offset.x, -offset.y))),
FastTransform::Transform { transform, inverse: Some(inverse), is_2d, } =>
Some(FastTransform::Transform {
transform: inverse,
@ -792,14 +793,14 @@ impl<Src, Dst> FastTransform<Src, Dst> {
}
}
impl<Src, Dst> From<TypedTransform3D<f32, Src, Dst>> for FastTransform<Src, Dst> {
fn from(transform: TypedTransform3D<f32, Src, Dst>) -> Self {
impl<Src, Dst> From<Transform3D<f32, Src, Dst>> for FastTransform<Src, Dst> {
fn from(transform: Transform3D<f32, Src, Dst>) -> Self {
FastTransform::with_transform(transform)
}
}
impl<Src, Dst> From<TypedVector2D<f32, Src>> for FastTransform<Src, Dst> {
fn from(vector: TypedVector2D<f32, Src>) -> Self {
impl<Src, Dst> From<Vector2D<f32, Src>> for FastTransform<Src, Dst> {
fn from(vector: Vector2D<f32, Src>) -> Self {
FastTransform::with_vector(vector)
}
}
@ -808,17 +809,17 @@ pub type LayoutFastTransform = FastTransform<LayoutPixel, LayoutPixel>;
pub type LayoutToWorldFastTransform = FastTransform<LayoutPixel, WorldPixel>;
pub fn project_rect<F, T>(
transform: &TypedTransform3D<f32, F, T>,
rect: &TypedRect<f32, F>,
bounds: &TypedRect<f32, T>,
) -> Option<TypedRect<f32, T>>
transform: &Transform3D<f32, F, T>,
rect: &Rect<f32, F>,
bounds: &Rect<f32, T>,
) -> Option<Rect<f32, T>>
where F: fmt::Debug
{
let homogens = [
transform.transform_point2d_homogeneous(&rect.origin),
transform.transform_point2d_homogeneous(&rect.top_right()),
transform.transform_point2d_homogeneous(&rect.bottom_left()),
transform.transform_point2d_homogeneous(&rect.bottom_right()),
transform.transform_point2d_homogeneous(rect.origin),
transform.transform_point2d_homogeneous(rect.top_right()),
transform.transform_point2d_homogeneous(rect.bottom_left()),
transform.transform_point2d_homogeneous(rect.bottom_right()),
];
// Note: we only do the full frustum collision when the polygon approaches the camera plane.
@ -844,19 +845,19 @@ pub fn project_rect<F, T>(
return None
}
Some(TypedRect::from_points(results
Some(Rect::from_points(results
.into_iter()
// filter out parts behind the view plane
.flat_map(|poly| &poly.points)
.map(|p| {
let mut homo = transform.transform_point2d_homogeneous(&p.to_2d());
let mut homo = transform.transform_point2d_homogeneous(p.to_2d());
homo.w = homo.w.max(0.00000001); // avoid infinite values
homo.to_point2d().unwrap()
})
))
} else {
// we just checked for all the points to be in positive hemisphere, so `unwrap` is valid
Some(TypedRect::from_points(&[
Some(Rect::from_points(&[
homogens[0].to_point2d().unwrap(),
homogens[1].to_point2d().unwrap(),
homogens[2].to_point2d().unwrap(),
@ -869,7 +870,7 @@ pub fn raster_rect_to_device_pixels(
rect: RasterRect,
device_pixel_scale: DevicePixelScale,
) -> DeviceRect {
let world_rect = rect * TypedScale::new(1.0);
let world_rect = rect * Scale::new(1.0);
let device_rect = world_rect * device_pixel_scale;
device_rect.round_out()
}
@ -1128,7 +1129,7 @@ impl<T: MallocSizeOf> MallocSizeOf for PrimaryArc<T> {
///
/// * Removed `xMajor` parameter.
pub fn scale_factors<Src, Dst>(
mat: &TypedTransform3D<f32, Src, Dst>
mat: &Transform3D<f32, Src, Dst>
) -> (f32, f32) {
// Determinant is just of the 2D component.
let det = mat.m11 * mat.m22 - mat.m12 * mat.m21;

Просмотреть файл

@ -20,7 +20,7 @@ bitflags = "1.0"
byteorder = "1.2.1"
derive_more = "0.13"
ipc-channel = {version = "0.11.0", optional = true}
euclid = { version = "0.19.9", features = ["serde"] }
euclid = { version = "0.20.0", features = ["serde"] }
malloc_size_of_derive = "0.1"
serde = { version = "=1.0.88", features = ["rc"] }
serde_derive = "=1.0.88"

Просмотреть файл

@ -206,7 +206,7 @@ pub struct StickyFrameDisplayItem {
/// The margins that should be maintained between the edge of the parent viewport and this
/// sticky frame. A margin of None indicates that the sticky frame should not stick at all
/// to that particular edge of the viewport.
pub margins: SideOffsets2D<Option<f32>>,
pub margins: SideOffsets2D<Option<f32>, LayoutPixel>,
/// The minimum and maximum vertical offsets for this sticky frame. Ignoring these constraints,
/// the sticky frame will continue to stick to the edge of the viewport as its original
@ -424,7 +424,7 @@ pub struct NinePatchBorder {
/// stretching.
/// Slices can be overlapping. In that case, the same pixels from the
/// 9-part image will show up in multiple parts of the resulting border.
pub slice: SideOffsets2D<i32>,
pub slice: DeviceIntSideOffsets,
/// Controls whether the center of the 9 patch image is rendered or
/// ignored. The center is never rendered if the slices are overlapping.
@ -440,7 +440,7 @@ pub struct NinePatchBorder {
/// The outset for the border.
/// TODO(mrobinson): This should be removed and handled by the client.
pub outset: SideOffsets2D<f32>,
pub outset: LayoutSideOffsets, // TODO: what unit is this in?
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize, PeekPoke)]

Просмотреть файл

@ -1408,7 +1408,7 @@ impl DisplayListBuilder {
&mut self,
parent_spatial_id: di::SpatialId,
frame_rect: LayoutRect,
margins: SideOffsets2D<Option<f32>>,
margins: SideOffsets2D<Option<f32>, LayoutPixel>,
vertical_offset_bounds: di::StickyOffsetBounds,
horizontal_offset_bounds: di::StickyOffsetBounds,
previously_applied_offset: LayoutVector2D,

Просмотреть файл

@ -4,7 +4,7 @@
#![deny(missing_docs)]
use euclid::{size2, TypedRect, num::Zero};
use euclid::{size2, Rect, num::Zero};
use peek_poke::PeekPoke;
use std::ops::{Add, Sub};
use std::sync::Arc;
@ -381,7 +381,7 @@ pub enum DirtyRect<T: Copy, U> {
/// Everything is Dirty, equivalent to Partial(image_bounds)
All,
/// Some specific amount is dirty
Partial(TypedRect<T, U>)
Partial(Rect<T, U>)
}
impl<T, U> DirtyRect<T, U>
@ -394,7 +394,7 @@ where
{
/// Creates an empty DirtyRect (indicating nothing is invalid)
pub fn empty() -> Self {
DirtyRect::Partial(TypedRect::zero())
DirtyRect::Partial(Rect::zero())
}
/// Returns whether the dirty rect is empty
@ -412,7 +412,7 @@ where
/// Maps over the contents of Partial.
pub fn map<F>(self, func: F) -> Self
where F: FnOnce(TypedRect<T, U>) -> TypedRect<T, U>,
where F: FnOnce(Rect<T, U>) -> Rect<T, U>,
{
use crate::DirtyRect::*;
@ -439,18 +439,18 @@ where
match (*self, *other) {
(All, rect) | (rect, All) => rect,
(Partial(rect1), Partial(rect2)) => Partial(rect1.intersection(&rect2)
.unwrap_or_else(TypedRect::zero))
.unwrap_or_else(Rect::zero))
}
}
/// Converts the dirty rect into a subrect of the given one via intersection.
pub fn to_subrect_of(&self, rect: &TypedRect<T, U>) -> TypedRect<T, U> {
pub fn to_subrect_of(&self, rect: &Rect<T, U>) -> Rect<T, U> {
use crate::DirtyRect::*;
match *self {
All => *rect,
Partial(dirty_rect) => dirty_rect.intersection(rect)
.unwrap_or_else(TypedRect::zero),
.unwrap_or_else(Rect::zero),
}
}
}
@ -460,8 +460,8 @@ impl<T: Copy, U> Clone for DirtyRect<T, U> {
fn clone(&self) -> Self { *self }
}
impl<T: Copy, U> From<TypedRect<T, U>> for DirtyRect<T, U> {
fn from(rect: TypedRect<T, U>) -> Self {
impl<T: Copy, U> From<Rect<T, U>> for DirtyRect<T, U> {
fn from(rect: Rect<T, U>) -> Self {
DirtyRect::Partial(rect)
}
}

Просмотреть файл

@ -13,8 +13,8 @@
//! in the context of coordinate systems.
pub use app_units::Au;
use euclid::{Length, TypedRect, TypedScale, TypedSize2D, TypedTransform3D, TypedTranslation2D};
use euclid::{TypedPoint2D, TypedPoint3D, TypedVector2D, TypedVector3D, TypedSideOffsets2D};
use euclid::{Length, Rect, Scale, Size2D, Transform3D, Translation2D};
use euclid::{Point2D, Point3D, Vector2D, Vector3D, SideOffsets2D};
use euclid::HomogeneousVector;
use peek_poke::PeekPoke;
// local imports
@ -25,16 +25,16 @@ use crate::image::DirtyRect;
#[derive(Hash, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
pub struct DevicePixel;
pub type DeviceIntRect = TypedRect<i32, DevicePixel>;
pub type DeviceIntPoint = TypedPoint2D<i32, DevicePixel>;
pub type DeviceIntSize = TypedSize2D<i32, DevicePixel>;
pub type DeviceIntRect = Rect<i32, DevicePixel>;
pub type DeviceIntPoint = Point2D<i32, DevicePixel>;
pub type DeviceIntSize = Size2D<i32, DevicePixel>;
pub type DeviceIntLength = Length<i32, DevicePixel>;
pub type DeviceIntSideOffsets = TypedSideOffsets2D<i32, DevicePixel>;
pub type DeviceIntSideOffsets = SideOffsets2D<i32, DevicePixel>;
pub type DeviceRect = TypedRect<f32, DevicePixel>;
pub type DevicePoint = TypedPoint2D<f32, DevicePixel>;
pub type DeviceVector2D = TypedVector2D<f32, DevicePixel>;
pub type DeviceSize = TypedSize2D<f32, DevicePixel>;
pub type DeviceRect = Rect<f32, DevicePixel>;
pub type DevicePoint = Point2D<f32, DevicePixel>;
pub type DeviceVector2D = Vector2D<f32, DevicePixel>;
pub type DeviceSize = Size2D<f32, DevicePixel>;
pub type DeviceHomogeneousVector = HomogeneousVector<f32, DevicePixel>;
/// Geometry in the coordinate system of the framebuffer in physical pixels.
@ -42,24 +42,24 @@ pub type DeviceHomogeneousVector = HomogeneousVector<f32, DevicePixel>;
#[derive(Hash, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
pub struct FramebufferPixel;
pub type FramebufferIntPoint = TypedPoint2D<i32, FramebufferPixel>;
pub type FramebufferIntSize = TypedSize2D<i32, FramebufferPixel>;
pub type FramebufferIntRect = TypedRect<i32, FramebufferPixel>;
pub type FramebufferIntPoint = Point2D<i32, FramebufferPixel>;
pub type FramebufferIntSize = Size2D<i32, FramebufferPixel>;
pub type FramebufferIntRect = Rect<i32, FramebufferPixel>;
/// Geometry in the coordinate system of a Picture (intermediate
/// surface) in physical pixels.
#[derive(Hash, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct PicturePixel;
pub type PictureIntRect = TypedRect<i32, PicturePixel>;
pub type PictureIntPoint = TypedPoint2D<i32, PicturePixel>;
pub type PictureIntSize = TypedSize2D<i32, PicturePixel>;
pub type PictureRect = TypedRect<f32, PicturePixel>;
pub type PicturePoint = TypedPoint2D<f32, PicturePixel>;
pub type PictureSize = TypedSize2D<f32, PicturePixel>;
pub type PicturePoint3D = TypedPoint3D<f32, PicturePixel>;
pub type PictureVector2D = TypedVector2D<f32, PicturePixel>;
pub type PictureVector3D = TypedVector3D<f32, PicturePixel>;
pub type PictureIntRect = Rect<i32, PicturePixel>;
pub type PictureIntPoint = Point2D<i32, PicturePixel>;
pub type PictureIntSize = Size2D<i32, PicturePixel>;
pub type PictureRect = Rect<f32, PicturePixel>;
pub type PicturePoint = Point2D<f32, PicturePixel>;
pub type PictureSize = Size2D<f32, PicturePixel>;
pub type PicturePoint3D = Point3D<f32, PicturePixel>;
pub type PictureVector2D = Vector2D<f32, PicturePixel>;
pub type PictureVector3D = Vector3D<f32, PicturePixel>;
/// Geometry gets rasterized in a given root coordinate space. This
/// is often the root spatial node (world space), but may be a local
@ -67,81 +67,81 @@ pub type PictureVector3D = TypedVector3D<f32, PicturePixel>;
#[derive(Hash, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct RasterPixel;
pub type RasterIntRect = TypedRect<i32, RasterPixel>;
pub type RasterIntPoint = TypedPoint2D<i32, RasterPixel>;
pub type RasterIntSize = TypedSize2D<i32, RasterPixel>;
pub type RasterRect = TypedRect<f32, RasterPixel>;
pub type RasterPoint = TypedPoint2D<f32, RasterPixel>;
pub type RasterSize = TypedSize2D<f32, RasterPixel>;
pub type RasterPoint3D = TypedPoint3D<f32, RasterPixel>;
pub type RasterVector2D = TypedVector2D<f32, RasterPixel>;
pub type RasterVector3D = TypedVector3D<f32, RasterPixel>;
pub type RasterIntRect = Rect<i32, RasterPixel>;
pub type RasterIntPoint = Point2D<i32, RasterPixel>;
pub type RasterIntSize = Size2D<i32, RasterPixel>;
pub type RasterRect = Rect<f32, RasterPixel>;
pub type RasterPoint = Point2D<f32, RasterPixel>;
pub type RasterSize = Size2D<f32, RasterPixel>;
pub type RasterPoint3D = Point3D<f32, RasterPixel>;
pub type RasterVector2D = Vector2D<f32, RasterPixel>;
pub type RasterVector3D = Vector3D<f32, RasterPixel>;
/// Geometry in a stacking context's local coordinate space (logical pixels).
#[derive(Hash, Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, Ord, PartialOrd, Deserialize, Serialize, PeekPoke)]
pub struct LayoutPixel;
pub type LayoutRect = TypedRect<f32, LayoutPixel>;
pub type LayoutPoint = TypedPoint2D<f32, LayoutPixel>;
pub type LayoutPoint3D = TypedPoint3D<f32, LayoutPixel>;
pub type LayoutVector2D = TypedVector2D<f32, LayoutPixel>;
pub type LayoutVector3D = TypedVector3D<f32, LayoutPixel>;
pub type LayoutSize = TypedSize2D<f32, LayoutPixel>;
pub type LayoutSideOffsets = TypedSideOffsets2D<f32, LayoutPixel>;
pub type LayoutRect = Rect<f32, LayoutPixel>;
pub type LayoutPoint = Point2D<f32, LayoutPixel>;
pub type LayoutPoint3D = Point3D<f32, LayoutPixel>;
pub type LayoutVector2D = Vector2D<f32, LayoutPixel>;
pub type LayoutVector3D = Vector3D<f32, LayoutPixel>;
pub type LayoutSize = Size2D<f32, LayoutPixel>;
pub type LayoutSideOffsets = SideOffsets2D<f32, LayoutPixel>;
pub type LayoutIntRect = TypedRect<i32, LayoutPixel>;
pub type LayoutIntPoint = TypedPoint2D<i32, LayoutPixel>;
pub type LayoutIntSize = TypedSize2D<i32, LayoutPixel>;
pub type LayoutIntRect = Rect<i32, LayoutPixel>;
pub type LayoutIntPoint = Point2D<i32, LayoutPixel>;
pub type LayoutIntSize = Size2D<i32, LayoutPixel>;
/// Geometry in the document's coordinate space (logical pixels).
#[derive(Hash, Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, Ord, PartialOrd)]
pub struct WorldPixel;
pub type WorldRect = TypedRect<f32, WorldPixel>;
pub type WorldPoint = TypedPoint2D<f32, WorldPixel>;
pub type WorldSize = TypedSize2D<f32, WorldPixel>;
pub type WorldPoint3D = TypedPoint3D<f32, WorldPixel>;
pub type WorldVector2D = TypedVector2D<f32, WorldPixel>;
pub type WorldVector3D = TypedVector3D<f32, WorldPixel>;
pub type WorldRect = Rect<f32, WorldPixel>;
pub type WorldPoint = Point2D<f32, WorldPixel>;
pub type WorldSize = Size2D<f32, WorldPixel>;
pub type WorldPoint3D = Point3D<f32, WorldPixel>;
pub type WorldVector2D = Vector2D<f32, WorldPixel>;
pub type WorldVector3D = Vector3D<f32, WorldPixel>;
/// Offset in number of tiles.
#[derive(Hash, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct Tiles;
pub type TileOffset = TypedPoint2D<i32, Tiles>;
pub type TileRange = TypedRect<i32, Tiles>;
pub type TileOffset = Point2D<i32, Tiles>;
pub type TileRange = Rect<i32, Tiles>;
/// Scaling ratio from world pixels to device pixels.
pub type DevicePixelScale = TypedScale<f32, WorldPixel, DevicePixel>;
pub type DevicePixelScale = Scale<f32, WorldPixel, DevicePixel>;
/// Scaling ratio from layout to world. Used for cases where we know the layout
/// is in world space, or specifically want to treat it this way.
pub type LayoutToWorldScale = TypedScale<f32, LayoutPixel, WorldPixel>;
pub type LayoutToWorldScale = Scale<f32, LayoutPixel, WorldPixel>;
/// A complete scaling ratio from layout space to device pixel space.
pub type LayoutToDeviceScale = TypedScale<f32, LayoutPixel, DevicePixel>;
pub type LayoutToDeviceScale = Scale<f32, LayoutPixel, DevicePixel>;
pub type LayoutTransform = TypedTransform3D<f32, LayoutPixel, LayoutPixel>;
pub type LayoutToWorldTransform = TypedTransform3D<f32, LayoutPixel, WorldPixel>;
pub type WorldToLayoutTransform = TypedTransform3D<f32, WorldPixel, LayoutPixel>;
pub type LayoutTransform = Transform3D<f32, LayoutPixel, LayoutPixel>;
pub type LayoutToWorldTransform = Transform3D<f32, LayoutPixel, WorldPixel>;
pub type WorldToLayoutTransform = Transform3D<f32, WorldPixel, LayoutPixel>;
pub type LayoutToPictureTransform = TypedTransform3D<f32, LayoutPixel, PicturePixel>;
pub type PictureToLayoutTransform = TypedTransform3D<f32, PicturePixel, LayoutPixel>;
pub type LayoutToPictureTransform = Transform3D<f32, LayoutPixel, PicturePixel>;
pub type PictureToLayoutTransform = Transform3D<f32, PicturePixel, LayoutPixel>;
pub type LayoutToRasterTransform = TypedTransform3D<f32, LayoutPixel, RasterPixel>;
pub type RasterToLayoutTransform = TypedTransform3D<f32, RasterPixel, LayoutPixel>;
pub type LayoutToRasterTransform = Transform3D<f32, LayoutPixel, RasterPixel>;
pub type RasterToLayoutTransform = Transform3D<f32, RasterPixel, LayoutPixel>;
pub type PictureToRasterTransform = TypedTransform3D<f32, PicturePixel, RasterPixel>;
pub type RasterToPictureTransform = TypedTransform3D<f32, RasterPixel, PicturePixel>;
pub type PictureToRasterTransform = Transform3D<f32, PicturePixel, RasterPixel>;
pub type RasterToPictureTransform = Transform3D<f32, RasterPixel, PicturePixel>;
// Fixed position coordinates, to avoid float precision errors.
pub type LayoutPointAu = TypedPoint2D<Au, LayoutPixel>;
pub type LayoutRectAu = TypedRect<Au, LayoutPixel>;
pub type LayoutSizeAu = TypedSize2D<Au, LayoutPixel>;
pub type LayoutVector2DAu = TypedVector2D<Au, LayoutPixel>;
pub type LayoutSideOffsetsAu = TypedSideOffsets2D<Au, LayoutPixel>;
pub type LayoutPointAu = Point2D<Au, LayoutPixel>;
pub type LayoutRectAu = Rect<Au, LayoutPixel>;
pub type LayoutSizeAu = Size2D<Au, LayoutPixel>;
pub type LayoutVector2DAu = Vector2D<Au, LayoutPixel>;
pub type LayoutSideOffsetsAu = SideOffsets2D<Au, LayoutPixel>;
pub type ImageDirtyRect = DirtyRect<i32, DevicePixel>;
pub type BlobDirtyRect = DirtyRect<i32, LayoutPixel>;
pub type BlobToDeviceTranslation = TypedTranslation2D<i32, LayoutPixel, DevicePixel>;
pub type BlobToDeviceTranslation = Translation2D<i32, LayoutPixel, DevicePixel>;
/// Stores two coordinates in texel space. The coordinates
/// are stored in texel coordinates because the texture atlas
@ -266,3 +266,27 @@ impl AuHelpers<LayoutSideOffsetsAu> for LayoutSideOffsets {
)
}
}
pub trait RectExt {
type Point;
fn top_left(&self) -> Self::Point;
fn top_right(&self) -> Self::Point;
fn bottom_left(&self) -> Self::Point;
fn bottom_right(&self) -> Self::Point;
}
impl<U> RectExt for Rect<f32, U> {
type Point = Point2D<f32, U>;
fn top_left(&self) -> Self::Point {
self.min()
}
fn top_right(&self) -> Self::Point {
Point2D::new(self.max_x(), self.min_y())
}
fn bottom_left(&self) -> Self::Point {
Point2D::new(self.min_x(), self.max_y())
}
fn bottom_right(&self) -> Self::Point {
self.max()
}
}

Просмотреть файл

@ -11,4 +11,4 @@ path = "lib.rs"
[dependencies]
app_units = "0.7"
euclid = "0.19"
euclid = "0.20"

Просмотреть файл

@ -316,25 +316,25 @@ impl<T: MallocSizeOf, Unit> MallocSizeOf for euclid::Length<T, Unit> {
}
}
impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::TypedScale<T, Src, Dst> {
impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::Scale<T, Src, Dst> {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.0.size_of(ops)
}
}
impl<T: MallocSizeOf, U> MallocSizeOf for euclid::TypedPoint2D<T, U> {
impl<T: MallocSizeOf, U> MallocSizeOf for euclid::Point2D<T, U> {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.x.size_of(ops) + self.y.size_of(ops)
}
}
impl<T: MallocSizeOf, U> MallocSizeOf for euclid::TypedRect<T, U> {
impl<T: MallocSizeOf, U> MallocSizeOf for euclid::Rect<T, U> {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.origin.size_of(ops) + self.size.size_of(ops)
}
}
impl<T: MallocSizeOf, U> MallocSizeOf for euclid::TypedSideOffsets2D<T, U> {
impl<T: MallocSizeOf, U> MallocSizeOf for euclid::SideOffsets2D<T, U> {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.top.size_of(ops) +
self.right.size_of(ops) +
@ -343,13 +343,13 @@ impl<T: MallocSizeOf, U> MallocSizeOf for euclid::TypedSideOffsets2D<T, U> {
}
}
impl<T: MallocSizeOf, U> MallocSizeOf for euclid::TypedSize2D<T, U> {
impl<T: MallocSizeOf, U> MallocSizeOf for euclid::Size2D<T, U> {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.width.size_of(ops) + self.height.size_of(ops)
}
}
impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::TypedTransform2D<T, Src, Dst> {
impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::Transform2D<T, Src, Dst> {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.m11.size_of(ops) +
self.m12.size_of(ops) +
@ -360,7 +360,7 @@ impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::TypedTransform2D<T, Src
}
}
impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::TypedTransform3D<T, Src, Dst> {
impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::Transform3D<T, Src, Dst> {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.m11.size_of(ops) +
self.m12.size_of(ops) +
@ -381,7 +381,7 @@ impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::TypedTransform3D<T, Src
}
}
impl<T: MallocSizeOf, U> MallocSizeOf for euclid::TypedVector2D<T, U> {
impl<T: MallocSizeOf, U> MallocSizeOf for euclid::Vector2D<T, U> {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.x.size_of(ops) + self.y.size_of(ops)
}

Просмотреть файл

@ -11,7 +11,7 @@ base64 = "0.10"
bincode = "1.0"
byteorder = "1.0"
env_logger = { version = "0.5", optional = true }
euclid = "0.19"
euclid = "0.20"
gleam = "0.6.2"
glutin = "0.21"
app_units = "0.7"

Просмотреть файл

@ -4,7 +4,7 @@
extern crate yaml_rust;
use euclid::{TypedPoint2D, TypedRect, TypedSize2D, TypedTransform3D, TypedVector2D};
use euclid::{Point2D, Rect, Size2D, Transform3D, Vector2D};
use image::{save_buffer, ColorType};
use crate::premultiply::unpremultiply;
use crate::scene::{Scene, SceneProperties};
@ -84,19 +84,19 @@ fn color_node(parent: &mut Table, key: &str, value: ColorF) {
yaml_node(parent, key, Yaml::String(color_to_string(value)));
}
fn point_node<U>(parent: &mut Table, key: &str, value: &TypedPoint2D<f32, U>) {
fn point_node<U>(parent: &mut Table, key: &str, value: &Point2D<f32, U>) {
f32_vec_node(parent, key, &[value.x, value.y]);
}
fn vector_node<U>(parent: &mut Table, key: &str, value: &TypedVector2D<f32, U>) {
fn vector_node<U>(parent: &mut Table, key: &str, value: &Vector2D<f32, U>) {
f32_vec_node(parent, key, &[value.x, value.y]);
}
fn size_node<U>(parent: &mut Table, key: &str, value: &TypedSize2D<f32, U>) {
fn size_node<U>(parent: &mut Table, key: &str, value: &Size2D<f32, U>) {
f32_vec_node(parent, key, &[value.width, value.height]);
}
fn rect_yaml<U>(value: &TypedRect<f32, U>) -> Yaml {
fn rect_yaml<U>(value: &Rect<f32, U>) -> Yaml {
f32_vec_yaml(
&[
value.origin.x,
@ -108,11 +108,11 @@ fn rect_yaml<U>(value: &TypedRect<f32, U>) -> Yaml {
)
}
fn rect_node<U>(parent: &mut Table, key: &str, value: &TypedRect<f32, U>) {
fn rect_node<U>(parent: &mut Table, key: &str, value: &Rect<f32, U>) {
yaml_node(parent, key, rect_yaml(value));
}
fn matrix4d_node<U1, U2>(parent: &mut Table, key: &str, value: &TypedTransform3D<f32, U1, U2>) {
fn matrix4d_node<U1, U2>(parent: &mut Table, key: &str, value: &Transform3D<f32, U1, U2>) {
f32_vec_node(parent, key, &value.to_row_major_array());
}

Просмотреть файл

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use euclid::{Angle, TypedSize2D};
use euclid::{Angle, Size2D};
use crate::parse_function::parse_function;
use std::f32;
use std::str::FromStr;
@ -179,7 +179,7 @@ fn make_rotation(
let transform =
LayoutTransform::identity().pre_rotate(axis_x, axis_y, axis_z, Angle::radians(theta));
pre_transform.pre_mul(&transform).pre_mul(&post_transform)
pre_transform.pre_transform(&transform).pre_transform(&post_transform)
}
pub fn make_perspective(
@ -189,7 +189,7 @@ pub fn make_perspective(
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_mul(&transform).pre_mul(&post_transform)
pre_transform.pre_transform(&transform).pre_transform(&post_transform)
}
// Create a skew matrix, specified in degrees.
@ -422,7 +422,7 @@ impl YamlHelper for Yaml {
break;
}
};
transform = transform.post_mul(&mx);
transform = transform.post_transform(&mx);
}
Some(transform)
}
@ -430,7 +430,7 @@ impl YamlHelper for Yaml {
let transform = array.iter().fold(
LayoutTransform::identity(),
|u, yaml| match yaml.as_transform(transform_origin) {
Some(ref transform) => u.pre_mul(transform),
Some(ref transform) => u.pre_transform(transform),
None => u,
},
);
@ -497,7 +497,7 @@ impl YamlHelper for Yaml {
if let Yaml::Integer(integer) = *self {
return LayoutSize::new(integer as f32, integer as f32);
}
self.as_size().unwrap_or(TypedSize2D::zero())
self.as_size().unwrap_or(Size2D::zero())
}
fn as_border_radius(&self) -> Option<BorderRadius> {

Просмотреть файл

@ -3652,8 +3652,8 @@ ImgDrawResult nsCSSBorderImageRenderer::CreateWebRenderCommands(
mImageSize.width / appUnitsPerDevPixel,
mImageSize.height / appUnitsPerDevPixel,
mFill,
wr::ToSideOffsets2D_i32(slice[0], slice[1], slice[2], slice[3]),
wr::ToSideOffsets2D_f32(outset[0], outset[1], outset[2], outset[3]),
wr::ToDeviceIntSideOffsets(slice[0], slice[1], slice[2], slice[3]),
wr::ToLayoutSideOffsets(outset[0], outset[1], outset[2], outset[3]),
wr::ToRepeatMode(mRepeatModeHorizontal),
wr::ToRepeatMode(mRepeatModeVertical)};
@ -3684,10 +3684,10 @@ ImgDrawResult nsCSSBorderImageRenderer::CreateWebRenderCommands(
wr::ToBorderWidths(widths[0], widths[1], widths[2], widths[3]),
(float)(mImageSize.width) / appUnitsPerDevPixel,
(float)(mImageSize.height) / appUnitsPerDevPixel, mFill,
wr::ToSideOffsets2D_i32(slice[0], slice[1], slice[2], slice[3]),
wr::ToDeviceIntSideOffsets(slice[0], slice[1], slice[2], slice[3]),
wr::ToLayoutPoint(startPoint), wr::ToLayoutPoint(endPoint), stops,
extendMode,
wr::ToSideOffsets2D_f32(outset[0], outset[1], outset[2],
wr::ToLayoutSideOffsets(outset[0], outset[1], outset[2],
outset[3]));
} else {
aBuilder.PushBorderRadialGradient(
@ -3695,7 +3695,7 @@ ImgDrawResult nsCSSBorderImageRenderer::CreateWebRenderCommands(
wr::ToBorderWidths(widths[0], widths[1], widths[2], widths[3]),
mFill, wr::ToLayoutPoint(lineStart),
wr::ToLayoutSize(gradientRadius), stops, extendMode,
wr::ToSideOffsets2D_f32(outset[0], outset[1], outset[2],
wr::ToLayoutSideOffsets(outset[0], outset[1], outset[2],
outset[3]));
}
break;

Просмотреть файл

@ -27,7 +27,7 @@ servo = [
app_units = "0.7"
crossbeam-channel = { version = "0.3", optional = true }
cssparser = "0.25"
euclid = "0.19"
euclid = "0.20"
hashglobe = { path = "../hashglobe" }
hyper = { version = "0.12", optional = true }
hyper_serde = { version = "0.11", optional = true }

Просмотреть файл

@ -625,25 +625,25 @@ impl<T: MallocSizeOf, Unit> MallocSizeOf for euclid::Length<T, Unit> {
}
}
impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::TypedScale<T, Src, Dst> {
impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::Scale<T, Src, Dst> {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.0.size_of(ops)
}
}
impl<T: MallocSizeOf, U> MallocSizeOf for euclid::TypedPoint2D<T, U> {
impl<T: MallocSizeOf, U> MallocSizeOf for euclid::Point2D<T, U> {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.x.size_of(ops) + self.y.size_of(ops)
}
}
impl<T: MallocSizeOf, U> MallocSizeOf for euclid::TypedRect<T, U> {
impl<T: MallocSizeOf, U> MallocSizeOf for euclid::Rect<T, U> {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.origin.size_of(ops) + self.size.size_of(ops)
}
}
impl<T: MallocSizeOf, U> MallocSizeOf for euclid::TypedSideOffsets2D<T, U> {
impl<T: MallocSizeOf, U> MallocSizeOf for euclid::SideOffsets2D<T, U> {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.top.size_of(ops) +
self.right.size_of(ops) +
@ -652,13 +652,13 @@ impl<T: MallocSizeOf, U> MallocSizeOf for euclid::TypedSideOffsets2D<T, U> {
}
}
impl<T: MallocSizeOf, U> MallocSizeOf for euclid::TypedSize2D<T, U> {
impl<T: MallocSizeOf, U> MallocSizeOf for euclid::Size2D<T, U> {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.width.size_of(ops) + self.height.size_of(ops)
}
}
impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::TypedTransform2D<T, Src, Dst> {
impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::Transform2D<T, Src, Dst> {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.m11.size_of(ops) +
self.m12.size_of(ops) +
@ -669,7 +669,7 @@ impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::TypedTransform2D<T, Src
}
}
impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::TypedTransform3D<T, Src, Dst> {
impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::Transform3D<T, Src, Dst> {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.m11.size_of(ops) +
self.m12.size_of(ops) +
@ -690,7 +690,7 @@ impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::TypedTransform3D<T, Src
}
}
impl<T: MallocSizeOf, U> MallocSizeOf for euclid::TypedVector2D<T, U> {
impl<T: MallocSizeOf, U> MallocSizeOf for euclid::Vector2D<T, U> {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.x.size_of(ops) + self.y.size_of(ops)
}

Просмотреть файл

@ -35,7 +35,7 @@ crossbeam-channel = { version = "0.3", optional = true }
derive_more = "0.13"
new_debug_unreachable = "1.0"
encoding_rs = {version = "0.8", optional = true}
euclid = "0.19"
euclid = "0.20"
fallible = { path = "../fallible" }
fxhash = "0.2"
hashglobe = { path = "../hashglobe" }

Просмотреть файл

@ -31,8 +31,8 @@ use crate::traversal_flags::TraversalFlags;
use app_units::Au;
#[cfg(feature = "servo")]
use crossbeam_channel::Sender;
use euclid::Size2D;
use euclid::TypedScale;
use euclid::default::Size2D;
use euclid::Scale;
use fxhash::FxHashMap;
#[cfg(feature = "servo")]
use parking_lot::RwLock;
@ -195,7 +195,7 @@ impl<'a> SharedStyleContext<'a> {
}
/// The device pixel ratio
pub fn device_pixel_ratio(&self) -> TypedScale<f32, CSSPixel, DevicePixel> {
pub fn device_pixel_ratio(&self) -> Scale<f32, CSSPixel, DevicePixel> {
self.stylist.device().device_pixel_ratio()
}

Просмотреть файл

@ -14,7 +14,7 @@ use crate::values::computed::CSSPixelLength;
use crate::values::computed::Resolution;
use crate::Atom;
use app_units::Au;
use euclid::Size2D;
use euclid::default::Size2D;
fn viewport_size(device: &Device) -> Size2D<Au> {
if let Some(pc) = device.pres_context() {

Просмотреть файл

@ -16,8 +16,8 @@ use crate::values::{CustomIdent, KeyframesName};
use app_units::Au;
use app_units::AU_PER_PX;
use cssparser::RGBA;
use euclid::Size2D;
use euclid::TypedScale;
use euclid::default::Size2D;
use euclid::Scale;
use servo_arc::Arc;
use std::fmt;
use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize, Ordering};
@ -247,20 +247,20 @@ impl Device {
}
/// Returns the device pixel ratio.
pub fn device_pixel_ratio(&self) -> TypedScale<f32, CSSPixel, DevicePixel> {
pub fn device_pixel_ratio(&self) -> Scale<f32, CSSPixel, DevicePixel> {
let pc = match self.pres_context() {
Some(pc) => pc,
None => return TypedScale::new(1.),
None => return Scale::new(1.),
};
let override_dppx = pc.mOverrideDPPX;
if override_dppx > 0.0 {
return TypedScale::new(override_dppx);
return Scale::new(override_dppx);
}
let au_per_dpx = pc.mCurAppUnitsPerDevPixel as f32;
let au_per_px = AU_PER_PX as f32;
TypedScale::new(au_per_px / au_per_dpx)
Scale::new(au_per_px / au_per_dpx)
}
/// Returns whether document colors are enabled.

Просмотреть файл

@ -6,7 +6,7 @@
use crate::properties::style_structs;
use euclid::num::Zero;
use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
use euclid::default::{Point2D, Rect, Size2D, SideOffsets2D};
use std::cmp::{max, min};
use std::fmt::{self, Debug, Error, Formatter};
use std::ops::{Add, Sub};

Просмотреть файл

@ -15,7 +15,7 @@ use crate::values::computed::CSSPixelLength;
use crate::values::KeyframesName;
use app_units::Au;
use cssparser::RGBA;
use euclid::{Size2D, TypedScale, TypedSize2D};
use euclid::{Size2D, Scale, Size2D};
use std::sync::atomic::{AtomicBool, AtomicIsize, Ordering};
use style_traits::viewport::ViewportConstraints;
use style_traits::{CSSPixel, DevicePixel};
@ -29,9 +29,9 @@ pub struct Device {
/// The current media type used by de device.
media_type: MediaType,
/// The current viewport size, in CSS pixels.
viewport_size: TypedSize2D<f32, CSSPixel>,
viewport_size: Size2D<f32, CSSPixel>,
/// The current device pixel ratio, from CSS pixels to device pixels.
device_pixel_ratio: TypedScale<f32, CSSPixel, DevicePixel>,
device_pixel_ratio: Scale<f32, CSSPixel, DevicePixel>,
/// The font size of the root element
/// This is set when computing the style of the root
@ -59,8 +59,8 @@ impl Device {
/// Trivially construct a new `Device`.
pub fn new(
media_type: MediaType,
viewport_size: TypedSize2D<f32, CSSPixel>,
device_pixel_ratio: TypedScale<f32, CSSPixel, DevicePixel>,
viewport_size: Size2D<f32, CSSPixel>,
device_pixel_ratio: Scale<f32, CSSPixel, DevicePixel>,
) -> Device {
Device {
media_type,
@ -140,7 +140,7 @@ impl Device {
}
/// Returns the device pixel ratio.
pub fn device_pixel_ratio(&self) -> TypedScale<f32, CSSPixel, DevicePixel> {
pub fn device_pixel_ratio(&self) -> Scale<f32, CSSPixel, DevicePixel> {
self.device_pixel_ratio
}

Просмотреть файл

@ -25,7 +25,7 @@ use crate::values::specified::{NonNegativeLengthPercentageOrAuto, ViewportPercen
use app_units::Au;
use cssparser::CowRcStr;
use cssparser::{parse_important, AtRuleParser, DeclarationListParser, DeclarationParser, Parser};
use euclid::TypedSize2D;
use euclid::Size2D;
use selectors::parser::SelectorParseErrorKind;
use std::borrow::Cow;
use std::cell::RefCell;
@ -832,7 +832,7 @@ impl MaybeNew for ViewportConstraints {
});
Some(ViewportConstraints {
size: TypedSize2D::new(width.to_f32_px(), height.to_f32_px()),
size: Size2D::new(width.to_f32_px(), height.to_f32_px()),
// TODO: compute a zoom factor for 'auto' as suggested by DEVICE-ADAPT § 10.
initial_zoom: PinchZoomFactor::new(initial_zoom.unwrap_or(1.)),

Просмотреть файл

@ -23,7 +23,7 @@ use crate::rule_cache::RuleCacheConditions;
use crate::Atom;
#[cfg(feature = "servo")]
use crate::Prefix;
use euclid::Size2D;
use euclid::default::Size2D;
use std::cell::RefCell;
use std::cmp;
use std::f32;

Просмотреть файл

@ -10,7 +10,7 @@ use crate::values::animated::ToAnimatedZero;
use crate::values::computed::{Angle, Integer, Length, LengthPercentage, Number, Percentage};
use crate::values::generics::transform as generic;
use crate::Zero;
use euclid::{Transform3D, Vector3D};
use euclid::default::{Transform3D, Vector3D};
pub use crate::values::generics::transform::TransformStyle;

Просмотреть файл

@ -5,7 +5,7 @@
//! Machinery to compute distances between animatable values.
use app_units::Au;
use euclid::Size2D;
use euclid::default::Size2D;
use std::iter::Sum;
use std::ops::Add;

Просмотреть файл

@ -12,7 +12,8 @@ use crate::values::specified::length::LengthPercentage as SpecifiedLengthPercent
use crate::values::{computed, CSSFloat};
use crate::Zero;
use app_units::Au;
use euclid::{self, Rect, Transform3D};
use euclid::default::{Rect, Transform3D};
use euclid;
use std::fmt::{self, Write};
use style_traits::{CssWriter, ToCss};
@ -562,7 +563,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 = transform.pre_mul(&matrix);
transform = transform.pre_transform(&matrix);
}
Ok((transform, contain_3d))

Просмотреть файл

@ -22,7 +22,7 @@ use crate::values::CSSFloat;
use crate::Zero;
use app_units::Au;
use cssparser::{Parser, Token};
use euclid::Size2D;
use euclid::default::Size2D;
use std::cmp;
use std::ops::{Add, Mul};
use style_traits::values::specified::AllowedNumericType;

Просмотреть файл

@ -17,7 +17,7 @@ gecko = []
app_units = "0.7"
cssparser = "0.25"
bitflags = "1.0"
euclid = "0.19"
euclid = "0.20"
lazy_static = "1"
malloc_size_of = { path = "../malloc_size_of" }
malloc_size_of_derive = "0.1"

Просмотреть файл

@ -6,7 +6,7 @@
use crate::{CSSPixel, CssWriter, ParseError, PinchZoomFactor, ToCss};
use cssparser::Parser;
use euclid::TypedSize2D;
use euclid::Size2D;
use std::fmt::{self, Write};
define_css_keyword_enum! {
@ -33,7 +33,7 @@ pub struct ViewportConstraints {
/// Width and height:
/// * https://drafts.csswg.org/css-device-adapt/#width-desc
/// * https://drafts.csswg.org/css-device-adapt/#height-desc
pub size: TypedSize2D<f32, CSSPixel>,
pub size: Size2D<f32, CSSPixel>,
/// <https://drafts.csswg.org/css-device-adapt/#zoom-desc>
pub initial_zoom: PinchZoomFactor,
/// <https://drafts.csswg.org/css-device-adapt/#min-max-width-desc>

Просмотреть файл

@ -13,7 +13,7 @@ doctest = false
byteorder = "1.0"
app_units = "0.7"
cssparser = "0.25"
euclid = "0.19"
euclid = "0.20"
html5ever = "0.22"
parking_lot = "0.8"
rayon = "1"

Просмотреть файл

@ -2,8 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use euclid::TypedScale;
use euclid::TypedSize2D;
use euclid::Scale;
use euclid::Size2D;
use servo_arc::Arc;
use servo_url::ServoUrl;
use std::borrow::ToOwned;
@ -27,7 +27,7 @@ where
let stylesheet = Stylesheet::from_str(
css, url, Origin::Author, media_list, lock,
None, None, QuirksMode::NoQuirks, 0);
let dummy = Device::new(MediaType::screen(), TypedSize2D::new(200.0, 100.0), TypedScale::new(1.0));
let dummy = Device::new(MediaType::screen(), Size2D::new(200.0, 100.0), Scale::new(1.0));
let mut rule_count = 0;
let guard = stylesheet.shared_lock.read();
for rule in stylesheet.iter_rules::<AllRules>(&dummy, &guard) {
@ -333,7 +333,7 @@ fn test_mq_malformed_expressions() {
#[test]
fn test_matching_simple() {
let device = Device::new(MediaType::screen(), TypedSize2D::new(200.0, 100.0), TypedScale::new(1.0));
let device = Device::new(MediaType::screen(), Size2D::new(200.0, 100.0), Scale::new(1.0));
media_query_test(&device, "@media not all { a { color: red; } }", 0);
media_query_test(&device, "@media not screen { a { color: red; } }", 0);
@ -349,7 +349,7 @@ fn test_matching_simple() {
#[test]
fn test_matching_width() {
let device = Device::new(MediaType::screen(), TypedSize2D::new(200.0, 100.0), TypedScale::new(1.0));
let device = Device::new(MediaType::screen(), Size2D::new(200.0, 100.0), Scale::new(1.0));
media_query_test(&device, "@media { a { color: red; } }", 1);
@ -390,7 +390,7 @@ fn test_matching_width() {
#[test]
fn test_matching_invalid() {
let device = Device::new(MediaType::screen(), TypedSize2D::new(200.0, 100.0), TypedScale::new(1.0));
let device = Device::new(MediaType::screen(), Size2D::new(200.0, 100.0), Scale::new(1.0));
media_query_test(&device, "@media fridge { a { color: red; } }", 0);
media_query_test(&device, "@media screen and (height: 100px) { a { color: red; } }", 0);

Просмотреть файл

@ -3,8 +3,8 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use cssparser::SourceLocation;
use euclid::TypedScale;
use euclid::TypedSize2D;
use euclid::Scale;
use euclid::Size2D;
use selectors::parser::{AncestorHashes, Selector};
use servo_arc::Arc;
use servo_atoms::Atom;
@ -179,7 +179,7 @@ fn test_insert() {
}
fn mock_stylist() -> Stylist {
let device = Device::new(MediaType::screen(), TypedSize2D::new(0f32, 0f32), TypedScale::new(1.0));
let device = Device::new(MediaType::screen(), Size2D::new(0f32, 0f32), Scale::new(1.0));
Stylist::new(device, QuirksMode::NoQuirks)
}

Просмотреть файл

@ -3,8 +3,8 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use cssparser::{Parser, ParserInput};
use euclid::TypedScale;
use euclid::TypedSize2D;
use euclid::Scale;
use euclid::Size2D;
use servo_arc::Arc;
use servo_config::prefs::{PREFS, PrefValue};
use servo_url::ServoUrl;
@ -96,7 +96,7 @@ macro_rules! viewport_length {
#[test]
fn empty_viewport_rule() {
let device = Device::new(MediaType::screen(), TypedSize2D::new(800., 600.), TypedScale::new(1.0));
let device = Device::new(MediaType::screen(), Size2D::new(800., 600.), Scale::new(1.0));
test_viewport_rule("@viewport {}", &device, |declarations, css| {
println!("{}", css);
@ -119,7 +119,7 @@ macro_rules! assert_decl_eq {
#[test]
fn simple_viewport_rules() {
let device = Device::new(MediaType::screen(), TypedSize2D::new(800., 600.), TypedScale::new(1.0));
let device = Device::new(MediaType::screen(), Size2D::new(800., 600.), Scale::new(1.0));
test_viewport_rule("@viewport { width: auto; height: auto;\
zoom: auto; min-zoom: 0; max-zoom: 200%;\
@ -191,7 +191,7 @@ fn simple_meta_viewport_contents() {
#[test]
fn cascading_within_viewport_rule() {
let device = Device::new(MediaType::screen(), TypedSize2D::new(800., 600.), TypedScale::new(1.0));
let device = Device::new(MediaType::screen(), Size2D::new(800., 600.), Scale::new(1.0));
// normal order of appearance
test_viewport_rule("@viewport { min-width: 200px; min-width: auto; }",
@ -257,7 +257,7 @@ fn cascading_within_viewport_rule() {
#[test]
fn multiple_stylesheets_cascading() {
PREFS.set("layout.viewport.enabled", PrefValue::Boolean(true));
let device = Device::new(MediaType::screen(), TypedSize2D::new(800., 600.), TypedScale::new(1.0));
let device = Device::new(MediaType::screen(), Size2D::new(800., 600.), Scale::new(1.0));
let shared_lock = SharedRwLock::new();
let stylesheets = vec![
stylesheet!("@viewport { min-width: 100px; min-height: 100px; zoom: 1; }",
@ -317,8 +317,8 @@ fn constrain_viewport() {
}
}
let initial_viewport = TypedSize2D::new(800., 600.);
let device = Device::new(MediaType::screen(), initial_viewport, TypedScale::new(1.0));
let initial_viewport = Size2D::new(800., 600.);
let device = Device::new(MediaType::screen(), initial_viewport, Scale::new(1.0));
let mut input = ParserInput::new("");
assert_eq!(ViewportConstraints::maybe_new(&device, from_css!(input), QuirksMode::NoQuirks), None);
@ -366,12 +366,12 @@ fn constrain_viewport() {
orientation: Orientation::Auto
}));
let initial_viewport = TypedSize2D::new(200., 150.);
let device = Device::new(MediaType::screen(), initial_viewport, TypedScale::new(1.0));
let initial_viewport = Size2D::new(200., 150.);
let device = Device::new(MediaType::screen(), initial_viewport, Scale::new(1.0));
let mut input = ParserInput::new("width: 320px auto");
assert_eq!(ViewportConstraints::maybe_new(&device, from_css!(input), QuirksMode::NoQuirks),
Some(ViewportConstraints {
size: TypedSize2D::new(320., 240.),
size: Size2D::new(320., 240.),
initial_zoom: PinchZoomFactor::new(1.),
min_zoom: None,

Просмотреть файл

@ -1 +1 @@
{"files":{"COPYRIGHT":"ec82b96487e9e778ee610c7ab245162464782cfa1f555c2299333f8dbe5c036a","Cargo.toml":"6ed8512d0e0c349a53eddd15a806e67e84359c1071d7d4a404f513cca091d5f5","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"62065228e42caebca7e7d7db1204cbb867033de5982ca4009928915e4095f3a3","README.md":"625bec69c76ce5423fdd05cfe46922b2680ec517f97c5854ce34798d1d8a9541","src/approxeq.rs":"6594377e8f6c20f88f628520d8de9b9a59c5892a0ee9a6ccd13c8400c1499911","src/approxord.rs":"087e0a8d24b8a9bed4c1cc571eec5e50cc7afa184c6ac4961c7409a69456ec7b","src/box2d.rs":"5e2d634cf2181fd9f556a600d4339cb6a098341ac71f72e0bc7521b3b3fb2f19","src/box3d.rs":"8d87e7e487d0772462cc2c6033bcd05f4fee44127c4aa0a4d72407ac6a02e03b","src/homogen.rs":"7b02aa671fffcb554557ad790f598bd5d7440dc1aa4a6d1c5a97d8bc3c8f64d6","src/length.rs":"3171315822707728b1bfbdd04a4190ffb7206b4bfc59e9dd072bb2caa05ff292","src/lib.rs":"e8bbae14e1b284fba3529af44396e488cbc48f8b3d20ddb26da5919d9c02601b","src/macros.rs":"3b475e84d00cceee6c7e96e9f2c97ba15d8dc7f4094efb82c5ed10bd60d86a64","src/num.rs":"4439479fad5729073e0bfe0b96b547672a237430d48e564519759b9550baa033","src/point.rs":"b51cf9b7713d9a48452d833cfbc97bb95e0c2202c4f77cadd02633ce80a600df","src/rect.rs":"2e4036f3f7e2ca62e6f9a52787ca9b9765b401a11cf1e70dff6c81142bdd91ed","src/rigid.rs":"e50a5df42add328ed5164e1954592406ce6d8f564beb4ca375c5cca920e93fbc","src/rotation.rs":"3d1a934a7c59bd7ca8501d17d463d5af41fb529c5aa8fe8c3bb8a2b236d4abc0","src/scale.rs":"fc07bcf47f3a1215023c830059f0d270e570cbd37fe8c367ef4a47b191f4ae3e","src/side_offsets.rs":"d9b1463672e1204bf8e7dd6fe0f7601eb75b6690ec6eb18debcee07f5ca92ee3","src/size.rs":"c4e38966c280ab5b4963961eebdbb12e0f448aea624cbe760b02ca2221a004e5","src/transform2d.rs":"7657d447993dc820e404ea9fbde6cb2900d874d4f5c735e85c6225c9f3b4110d","src/transform3d.rs":"af3d909ee103d02fec5f59599055cc3cee5217975b030e0089e1f1d99ad5139e","src/translation.rs":"b21d1d81a34b80d3285d42f33e8039fdb787749f017d2a7a2295d036c2f50548","src/trig.rs":"97a263c4f178b0332501659ca8143f9f637a0755aca189dd31ac551bcd4cb73c","src/vector.rs":"dcd0904757ed0e7d12da1c612746da3e32c56e2248ec13041d1f3786811af51c"},"package":"596b99621b9477e7a5f94d2d8dd13a9c5c302ac358b822c67a42b6f1054450e1"}
{"files":{"COPYRIGHT":"ec82b96487e9e778ee610c7ab245162464782cfa1f555c2299333f8dbe5c036a","Cargo.toml":"7ae5531c88ac476361c06e6ee5531839eff3b301c66ba05619570b3ab7926467","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"62065228e42caebca7e7d7db1204cbb867033de5982ca4009928915e4095f3a3","README.md":"625bec69c76ce5423fdd05cfe46922b2680ec517f97c5854ce34798d1d8a9541","src/approxeq.rs":"6594377e8f6c20f88f628520d8de9b9a59c5892a0ee9a6ccd13c8400c1499911","src/approxord.rs":"087e0a8d24b8a9bed4c1cc571eec5e50cc7afa184c6ac4961c7409a69456ec7b","src/box2d.rs":"0dc013b9bfe088e62df8675674a5430580ecfaff202d0966ba5d316e7ff0165e","src/box3d.rs":"f15962fa34ef4dec099ca7403651ac92d5be55eba7aee0300b1a2837643dcb86","src/homogen.rs":"5c14355182b4fb7c148fc65c1f63b25607019ae8d763e187d659925e2ca210a3","src/length.rs":"b1f44beb961b193bea814f5a15aee713cab97d076de13e51e294891fd7153f27","src/lib.rs":"d58eecf5847b37f68ac6604c5b5a16962756faf04f9af1f5293228486b120378","src/macros.rs":"3b475e84d00cceee6c7e96e9f2c97ba15d8dc7f4094efb82c5ed10bd60d86a64","src/nonempty.rs":"865d51dc1ae785ee2e6e94eb2ee935f29a86b9efa8daa322bca7992fa9ae70fc","src/num.rs":"4439479fad5729073e0bfe0b96b547672a237430d48e564519759b9550baa033","src/point.rs":"b0eeed9f99cdd81525dd32b4d76caff862447e129b29bf55d003a35425e93ab6","src/rect.rs":"8298e2b67c7aadd255a53d42a6e5b19968aa47fcff05f8c60f4073da0a808dfc","src/rigid.rs":"aab59591562938695e63487230504b2d94df6e3a7b7740069166c8499d4fa930","src/rotation.rs":"307b22df279f30e4ac4aa35a0d69fb7f9196bd553c06b7f519692655e1e353d3","src/scale.rs":"6a4c3da9444c72e967d5217bbe5442a8517448857cb32472f883d6da58b8f846","src/side_offsets.rs":"eaa52aa64f0fa041fbd5c1c9165a01614db6c37d4746a56c3294a388bd5e0616","src/size.rs":"b3478be99f4409d3083e7553f5906c8ac314beddb83cc87492415c02785b8311","src/transform2d.rs":"8a0b4f097c8e98408dfe709b3ef0e8530562a6e1b68f62d6cd86c906cc0bb7eb","src/transform3d.rs":"6a6d56b67fdb1b6d4bfd725959d6b95cf4fa5ffbc272ae9f1508a400a3a4b30e","src/translation.rs":"67afb126179e3cb5a2c1bd462a8f5c87630233a68f63ff6a2194dbd3b229d734","src/trig.rs":"97a263c4f178b0332501659ca8143f9f637a0755aca189dd31ac551bcd4cb73c","src/vector.rs":"ca39c30729f781dd5e64b5fea1516e676b6ab4fc57788895fa2ca5309ad73ec3"},"package":"2c4786521fec183792e755bf32cd0188e4e7628c6d0fcfd51426435b9081a106"}

8
third_party/rust/euclid/Cargo.toml поставляемый
Просмотреть файл

@ -12,7 +12,7 @@
[package]
name = "euclid"
version = "0.19.9"
version = "0.20.0"
authors = ["The Servo Project Developers"]
description = "Geometry primitives"
documentation = "https://docs.rs/euclid/"
@ -20,9 +20,6 @@ keywords = ["matrix", "vector", "linear-algebra", "geometry"]
categories = ["science"]
license = "MIT / Apache-2.0"
repository = "https://github.com/servo/euclid"
[dependencies.euclid_macros]
version = "0.1"
[dependencies.mint]
version = "0.5.1"
optional = true
@ -34,9 +31,6 @@ version = "0.2"
version = "1.0"
features = ["serde_derive"]
optional = true
[dev-dependencies.rand]
version = "0.4"
[dev-dependencies.serde_test]
version = "1.0"

232
third_party/rust/euclid/src/box2d.rs поставляемый
Просмотреть файл

@ -8,13 +8,14 @@
// except according to those terms.
use super::UnknownUnit;
use scale::TypedScale;
use scale::Scale;
use num::*;
use rect::TypedRect;
use point::{point2, TypedPoint2D};
use vector::{vec2, TypedVector2D};
use side_offsets::TypedSideOffsets2D;
use size::TypedSize2D;
use rect::Rect;
use point::{point2, Point2D};
use vector::{vec2, Vector2D};
use side_offsets::SideOffsets2D;
use size::Size2D;
use nonempty::NonEmpty;
use approxord::{min, max};
use num_traits::NumCast;
@ -32,73 +33,70 @@ use core::ops::{Add, Div, Mul, Sub};
#[repr(C)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(bound(serialize = "T: Serialize", deserialize = "T: Deserialize<'de>")))]
pub struct TypedBox2D<T, U> {
pub min: TypedPoint2D<T, U>,
pub max: TypedPoint2D<T, U>,
pub struct Box2D<T, U> {
pub min: Point2D<T, U>,
pub max: Point2D<T, U>,
}
/// The default box 2d type with no unit.
pub type Box2D<T> = TypedBox2D<T, UnknownUnit>;
impl<T: Hash, U> Hash for TypedBox2D<T, U> {
impl<T: Hash, U> Hash for Box2D<T, U> {
fn hash<H: Hasher>(&self, h: &mut H) {
self.min.hash(h);
self.max.hash(h);
}
}
impl<T: Copy, U> Copy for TypedBox2D<T, U> {}
impl<T: Copy, U> Copy for Box2D<T, U> {}
impl<T: Copy, U> Clone for TypedBox2D<T, U> {
impl<T: Copy, U> Clone for Box2D<T, U> {
fn clone(&self) -> Self {
*self
}
}
impl<T: PartialEq, U> PartialEq<TypedBox2D<T, U>> for TypedBox2D<T, U> {
impl<T: PartialEq, U> PartialEq<Box2D<T, U>> for Box2D<T, U> {
fn eq(&self, other: &Self) -> bool {
self.min.eq(&other.min) && self.max.eq(&other.max)
}
}
impl<T: Eq, U> Eq for TypedBox2D<T, U> {}
impl<T: Eq, U> Eq for Box2D<T, U> {}
impl<T: fmt::Debug, U> fmt::Debug for TypedBox2D<T, U> {
impl<T: fmt::Debug, U> fmt::Debug for Box2D<T, U> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "TypedBox2D({:?}, {:?})", self.min, self.max)
write!(f, "Box2D({:?}, {:?})", self.min, self.max)
}
}
impl<T: fmt::Display, U> fmt::Display for TypedBox2D<T, U> {
impl<T: fmt::Display, U> fmt::Display for Box2D<T, U> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "Box2D({}, {})", self.min, self.max)
}
}
impl<T, U> TypedBox2D<T, U> {
impl<T, U> Box2D<T, U> {
/// Constructor.
pub fn new(min: TypedPoint2D<T, U>, max: TypedPoint2D<T, U>) -> Self {
TypedBox2D {
pub fn new(min: Point2D<T, U>, max: Point2D<T, U>) -> Self {
Box2D {
min,
max,
}
}
}
impl<T, U> TypedBox2D<T, U>
impl<T, U> Box2D<T, U>
where
T: Copy + Zero + PartialOrd,
{
/// Creates a Box2D of the given size, at offset zero.
#[inline]
pub fn from_size(size: TypedSize2D<T, U>) -> Self {
let zero = TypedPoint2D::zero();
pub fn from_size(size: Size2D<T, U>) -> Self {
let zero = Point2D::zero();
let point = size.to_vector().to_point();
TypedBox2D::from_points(&[zero, point])
Box2D::from_points(&[zero, point])
}
}
impl<T, U> TypedBox2D<T, U>
impl<T, U> Box2D<T, U>
where
T: Copy + PartialOrd,
{
@ -117,6 +115,15 @@ where
self.max.x <= self.min.x || self.max.y <= self.min.y
}
#[inline]
pub fn to_non_empty(&self) -> Option<NonEmpty<Self>> {
if self.is_empty_or_negative() {
return None;
}
Some(NonEmpty(*self))
}
/// Returns true if the two boxes intersect.
#[inline]
pub fn intersects(&self, other: &Self) -> bool {
@ -131,7 +138,7 @@ where
/// The result is a negative box if the boxes do not intersect.
#[inline]
pub fn intersection(&self, other: &Self) -> Self {
TypedBox2D {
Box2D {
min: point2(
max(self.min.x, other.min.x),
max(self.min.y, other.min.y),
@ -145,29 +152,32 @@ where
/// Computes the intersection of two boxes, returning `None` if the boxes do not intersect.
#[inline]
pub fn try_intersection(&self, other: &Self) -> Option<Self> {
pub fn try_intersection(&self, other: &Self) -> Option<NonEmpty<Self>> {
let intersection = self.intersection(other);
if intersection.is_negative() {
return None;
}
Some(intersection)
Some(NonEmpty(intersection))
}
}
impl<T, U> TypedBox2D<T, U>
impl<T, U> Box2D<T, U>
where
T: Copy + Add<T, Output = T>,
{
/// Returns the same box, translated by a vector.
#[inline]
pub fn translate(&self, by: &TypedVector2D<T, U>) -> Self {
Self::new(self.min + *by, self.max + *by)
pub fn translate(&self, by: Vector2D<T, U>) -> Self {
Box2D {
min: self.min + by,
max: self.max + by,
}
}
}
impl<T, U> TypedBox2D<T, U>
impl<T, U> Box2D<T, U>
where
T: Copy + PartialOrd + Zero,
{
@ -175,13 +185,13 @@ where
/// in the box if they are on the front, left or top faces, but outside if they
/// are on the back, right or bottom faces.
#[inline]
pub fn contains(&self, p: &TypedPoint2D<T, U>) -> bool {
pub fn contains(&self, p: Point2D<T, U>) -> bool {
self.min.x <= p.x && p.x < self.max.x
&& self.min.y <= p.y && p.y < self.max.y
}
}
impl<T, U> TypedBox2D<T, U>
impl<T, U> Box2D<T, U>
where
T: Copy + PartialOrd + Zero + Sub<T, Output = T>,
{
@ -196,40 +206,40 @@ where
}
}
impl<T, U> TypedBox2D<T, U>
impl<T, U> Box2D<T, U>
where
T: Copy + Sub<T, Output = T>,
{
#[inline]
pub fn size(&self)-> TypedSize2D<T, U> {
pub fn size(&self)-> Size2D<T, U> {
(self.max - self.min).to_size()
}
#[inline]
pub fn to_rect(&self) -> TypedRect<T, U> {
TypedRect {
pub fn to_rect(&self) -> Rect<T, U> {
Rect {
origin: self.min,
size: self.size(),
}
}
}
impl<T, U> TypedBox2D<T, U>
impl<T, U> Box2D<T, U>
where
T: Copy + PartialEq + Add<T, Output = T> + Sub<T, Output = T>,
{
/// Inflates the box by the specified sizes on each side respectively.
#[inline]
#[cfg_attr(feature = "unstable", must_use)]
#[must_use]
pub fn inflate(&self, width: T, height: T) -> Self {
TypedBox2D {
Box2D {
min: point2(self.min.x - width, self.min.y - height),
max: point2(self.max.x + width, self.max.y + height),
}
}
}
impl<T, U> TypedBox2D<T, U>
impl<T, U> Box2D<T, U>
where
T: Copy + Zero + PartialOrd + Add<T, Output = T> + Sub<T, Output = T>,
{
@ -237,8 +247,8 @@ where
///
/// Subtracts the side offsets from all sides. The horizontal, vertical
/// and applicate offsets must not be larger than the original side length.
pub fn inner_box(&self, offsets: TypedSideOffsets2D<T, U>) -> Self {
TypedBox2D {
pub fn inner_box(&self, offsets: SideOffsets2D<T, U>) -> Self {
Box2D {
min: self.min + vec2(offsets.left, offsets.top),
max: self.max - vec2(offsets.right, offsets.bottom),
}
@ -247,8 +257,8 @@ where
/// Calculate the b and position of an outer box.
///
/// Add the offsets to all sides. The expanded box is returned.
pub fn outer_box(&self, offsets: TypedSideOffsets2D<T, U>) -> Self {
TypedBox2D {
pub fn outer_box(&self, offsets: SideOffsets2D<T, U>) -> Self {
Box2D {
min: self.min - vec2(offsets.left, offsets.top),
max: self.max + vec2(offsets.right, offsets.bottom),
}
@ -256,7 +266,7 @@ where
}
impl<T, U> TypedBox2D<T, U>
impl<T, U> Box2D<T, U>
where
T: Copy + Zero + PartialOrd,
{
@ -264,14 +274,14 @@ where
pub fn from_points<I>(points: I) -> Self
where
I: IntoIterator,
I::Item: Borrow<TypedPoint2D<T, U>>,
I::Item: Borrow<Point2D<T, U>>,
{
let mut points = points.into_iter();
// Need at least 2 different points for a valid box (ie: volume > 0).
let (mut min_x, mut min_y) = match points.next() {
Some(first) => (first.borrow().x, first.borrow().y),
None => return TypedBox2D::zero(),
None => return Box2D::zero(),
};
let (mut max_x, mut max_y) = (min_x, min_y);
@ -294,7 +304,7 @@ where
match points.next() {
Some(second) => assign_min_max(second),
None => return TypedBox2D::zero(),
None => return Box2D::zero(),
}
for point in points {
@ -302,14 +312,14 @@ where
}
}
TypedBox2D {
Box2D {
min: point2(min_x, min_y),
max: point2(max_x, max_y),
}
}
}
impl<T, U> TypedBox2D<T, U>
impl<T, U> Box2D<T, U>
where
T: Copy + One + Add<Output = T> + Sub<Output = T> + Mul<Output = T>,
{
@ -325,23 +335,23 @@ where
}
}
impl<T, U> TypedBox2D<T, U>
impl<T, U> Box2D<T, U>
where
T: Copy + One + Add<Output = T> + Div<Output = T>,
{
pub fn center(&self) -> TypedPoint2D<T, U> {
pub fn center(&self) -> Point2D<T, U> {
let two = T::one() + T::one();
(self.min + self.max.to_vector()) / two
}
}
impl<T, U> TypedBox2D<T, U>
impl<T, U> Box2D<T, U>
where
T: Copy + PartialOrd,
{
#[inline]
pub fn union(&self, other: &Self) -> Self {
TypedBox2D {
Box2D {
min: point2(
min(self.min.x, other.min.x),
min(self.min.y, other.min.y),
@ -354,7 +364,7 @@ where
}
}
impl<T, U> TypedBox2D<T, U>
impl<T, U> Box2D<T, U>
where
T: Copy,
{
@ -363,14 +373,14 @@ where
where
T: Mul<S, Output = T>
{
TypedBox2D {
Box2D {
min: point2(self.min.x * x, self.min.y * y),
max: point2(self.max.x * x, self.max.y * y),
}
}
}
impl<T, U> TypedBox2D<T, U>
impl<T, U> Box2D<T, U>
where
T: Copy + Mul<T, Output = T> + Sub<T, Output = T>,
{
@ -381,17 +391,17 @@ where
}
}
impl<T, U> TypedBox2D<T, U>
impl<T, U> Box2D<T, U>
where
T: Copy + Zero,
{
/// Constructor, setting all sides to zero.
pub fn zero() -> Self {
TypedBox2D::new(TypedPoint2D::zero(), TypedPoint2D::zero())
Box2D::new(Point2D::zero(), Point2D::zero())
}
}
impl<T, U> TypedBox2D<T, U>
impl<T, U> Box2D<T, U>
where
T: PartialEq,
{
@ -402,69 +412,69 @@ where
}
}
impl<T, U> Mul<T> for TypedBox2D<T, U>
impl<T, U> Mul<T> for Box2D<T, U>
where
T: Copy + Mul<T, Output = T>,
{
type Output = Self;
#[inline]
fn mul(self, scale: T) -> Self {
TypedBox2D::new(self.min * scale, self.max * scale)
Box2D::new(self.min * scale, self.max * scale)
}
}
impl<T, U> Div<T> for TypedBox2D<T, U>
impl<T, U> Div<T> for Box2D<T, U>
where
T: Copy + Div<T, Output = T>,
{
type Output = Self;
#[inline]
fn div(self, scale: T) -> Self {
TypedBox2D::new(self.min / scale, self.max / scale)
Box2D::new(self.min / scale, self.max / scale)
}
}
impl<T, U1, U2> Mul<TypedScale<T, U1, U2>> for TypedBox2D<T, U1>
impl<T, U1, U2> Mul<Scale<T, U1, U2>> for Box2D<T, U1>
where
T: Copy + Mul<T, Output = T>,
{
type Output = TypedBox2D<T, U2>;
type Output = Box2D<T, U2>;
#[inline]
fn mul(self, scale: TypedScale<T, U1, U2>) -> TypedBox2D<T, U2> {
TypedBox2D::new(self.min * scale, self.max * scale)
fn mul(self, scale: Scale<T, U1, U2>) -> Box2D<T, U2> {
Box2D::new(self.min * scale, self.max * scale)
}
}
impl<T, U1, U2> Div<TypedScale<T, U1, U2>> for TypedBox2D<T, U2>
impl<T, U1, U2> Div<Scale<T, U1, U2>> for Box2D<T, U2>
where
T: Copy + Div<T, Output = T>,
{
type Output = TypedBox2D<T, U1>;
type Output = Box2D<T, U1>;
#[inline]
fn div(self, scale: TypedScale<T, U1, U2>) -> TypedBox2D<T, U1> {
TypedBox2D::new(self.min / scale, self.max / scale)
fn div(self, scale: Scale<T, U1, U2>) -> Box2D<T, U1> {
Box2D::new(self.min / scale, self.max / scale)
}
}
impl<T, Unit> TypedBox2D<T, Unit>
impl<T, Unit> Box2D<T, Unit>
where
T: Copy,
{
/// Drop the units, preserving only the numeric value.
pub fn to_untyped(&self) -> Box2D<T> {
TypedBox2D::new(self.min.to_untyped(), self.max.to_untyped())
pub fn to_untyped(&self) -> Box2D<T, UnknownUnit> {
Box2D::new(self.min.to_untyped(), self.max.to_untyped())
}
/// Tag a unitless value with units.
pub fn from_untyped(c: &Box2D<T>) -> TypedBox2D<T, Unit> {
TypedBox2D::new(
TypedPoint2D::from_untyped(&c.min),
TypedPoint2D::from_untyped(&c.max),
pub fn from_untyped(c: &Box2D<T, UnknownUnit>) -> Box2D<T, Unit> {
Box2D::new(
Point2D::from_untyped(c.min),
Point2D::from_untyped(c.max),
)
}
}
impl<T0, Unit> TypedBox2D<T0, Unit>
impl<T0, Unit> Box2D<T0, Unit>
where
T0: NumCast + Copy,
{
@ -473,8 +483,8 @@ where
/// 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(), round_in or round_out() before casting.
pub fn cast<T1: NumCast + Copy>(&self) -> TypedBox2D<T1, Unit> {
TypedBox2D::new(
pub fn cast<T1: NumCast + Copy>(&self) -> Box2D<T1, Unit> {
Box2D::new(
self.min.cast(),
self.max.cast(),
)
@ -485,15 +495,15 @@ where
/// 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(), round_in or round_out() before casting.
pub fn try_cast<T1: NumCast + Copy>(&self) -> Option<TypedBox2D<T1, Unit>> {
pub fn try_cast<T1: NumCast + Copy>(&self) -> Option<Box2D<T1, Unit>> {
match (self.min.try_cast(), self.max.try_cast()) {
(Some(a), Some(b)) => Some(TypedBox2D::new(a, b)),
(Some(a), Some(b)) => Some(Box2D::new(a, b)),
_ => None,
}
}
}
impl<T, U> TypedBox2D<T, U>
impl<T, U> Box2D<T, U>
where
T: Round,
{
@ -506,44 +516,44 @@ where
/// avoid pixel rounding errors.
/// Note that this is *not* rounding to nearest integer if the values are negative.
/// They are always rounding as floor(n + 0.5).
#[cfg_attr(feature = "unstable", must_use)]
#[must_use]
pub fn round(&self) -> Self {
TypedBox2D::new(self.min.round(), self.max.round())
Box2D::new(self.min.round(), self.max.round())
}
}
impl<T, U> TypedBox2D<T, U>
impl<T, U> Box2D<T, U>
where
T: Floor + Ceil,
{
/// Return a box with faces/edges rounded to integer coordinates, such that
/// the original box contains the resulting box.
#[cfg_attr(feature = "unstable", must_use)]
#[must_use]
pub fn round_in(&self) -> Self {
let min = self.min.ceil();
let max = self.max.floor();
TypedBox2D { min, max }
Box2D { min, max }
}
/// Return a box with faces/edges rounded to integer coordinates, such that
/// the original box is contained in the resulting box.
#[cfg_attr(feature = "unstable", must_use)]
#[must_use]
pub fn round_out(&self) -> Self {
let min = self.min.floor();
let max = self.max.ceil();
TypedBox2D { min, max }
Box2D { min, max }
}
}
// Convenience functions for common casts
impl<T: NumCast + Copy, Unit> TypedBox2D<T, Unit> {
impl<T: NumCast + Copy, Unit> Box2D<T, Unit> {
/// Cast into an `f32` box.
pub fn to_f32(&self) -> TypedBox2D<f32, Unit> {
pub fn to_f32(&self) -> Box2D<f32, Unit> {
self.cast()
}
/// Cast into an `f64` box.
pub fn to_f64(&self) -> TypedBox2D<f64, Unit> {
pub fn to_f64(&self) -> Box2D<f64, Unit> {
self.cast()
}
@ -552,7 +562,7 @@ impl<T: NumCast + Copy, Unit> TypedBox2D<T, Unit> {
/// When casting from floating point boxes, it is worth considering whether
/// to `round()`, `round_in()` or `round_out()` before the cast in order to
/// obtain the desired conversion behavior.
pub fn to_usize(&self) -> TypedBox2D<usize, Unit> {
pub fn to_usize(&self) -> Box2D<usize, Unit> {
self.cast()
}
@ -561,7 +571,7 @@ impl<T: NumCast + Copy, Unit> TypedBox2D<T, Unit> {
/// When casting from floating point boxes, it is worth considering whether
/// to `round()`, `round_in()` or `round_out()` before the cast in order to
/// obtain the desired conversion behavior.
pub fn to_u32(&self) -> TypedBox2D<u32, Unit> {
pub fn to_u32(&self) -> Box2D<u32, Unit> {
self.cast()
}
@ -570,7 +580,7 @@ impl<T: NumCast + Copy, Unit> TypedBox2D<T, Unit> {
/// When casting from floating point boxes, it is worth considering whether
/// to `round()`, `round_in()` or `round_out()` before the cast in order to
/// obtain the desired conversion behavior.
pub fn to_i32(&self) -> TypedBox2D<i32, Unit> {
pub fn to_i32(&self) -> Box2D<i32, Unit> {
self.cast()
}
@ -579,16 +589,16 @@ impl<T: NumCast + Copy, Unit> TypedBox2D<T, Unit> {
/// When casting from floating point boxes, it is worth considering whether
/// to `round()`, `round_in()` or `round_out()` before the cast in order to
/// obtain the desired conversion behavior.
pub fn to_i64(&self) -> TypedBox2D<i64, Unit> {
pub fn to_i64(&self) -> Box2D<i64, Unit> {
self.cast()
}
}
impl<T, U> From<TypedSize2D<T, U>> for TypedBox2D<T, U>
impl<T, U> From<Size2D<T, U>> for Box2D<T, U>
where
T: Copy + Zero + PartialOrd,
{
fn from(b: TypedSize2D<T, U>) -> Self {
fn from(b: Size2D<T, U>) -> Self {
Self::from_size(b)
}
}
@ -596,9 +606,9 @@ where
#[cfg(test)]
mod tests {
use side_offsets::SideOffsets2D;
use size::size2;
use point::Point2D;
use super::*;
use {Point2D, point2, vec2, size2};
use default::Box2D;
//use super::*;
#[test]
fn test_size() {
@ -688,7 +698,7 @@ mod tests {
let b = Box2D::from_size(size);
assert_eq!(b.center(), center);
let translation = vec2(10.0, 2.5);
let b = b.translate(&translation);
let b = b.translate(translation);
center += translation;
assert_eq!(b.center(), center);
assert_eq!(b.max.x, 25.0);
@ -760,7 +770,7 @@ mod tests {
#[test]
fn test_contains() {
let b = Box2D::from_points(&[point2(-20.0, -20.0), point2(20.0, 20.0)]);
assert!(b.contains(&point2(-15.3, 10.5)));
assert!(b.contains(point2(-15.3, 10.5)));
}
#[test]

253
third_party/rust/euclid/src/box3d.rs поставляемый
Просмотреть файл

@ -8,13 +8,13 @@
// except according to those terms.
use super::UnknownUnit;
use length::Length;
use scale::TypedScale;
use scale::Scale;
use num::*;
use point::TypedPoint3D;
use vector::TypedVector3D;
use size::TypedSize3D;
use point::Point3D;
use vector::Vector3D;
use size::Size3D;
use approxord::{min, max};
use nonempty::NonEmpty;
use num_traits::NumCast;
#[cfg(feature = "serde")]
@ -31,73 +31,70 @@ use core::ops::{Add, Div, Mul, Sub};
#[repr(C)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(bound(serialize = "T: Serialize", deserialize = "T: Deserialize<'de>")))]
pub struct TypedBox3D<T, U> {
pub min: TypedPoint3D<T, U>,
pub max: TypedPoint3D<T, U>,
pub struct Box3D<T, U> {
pub min: Point3D<T, U>,
pub max: Point3D<T, U>,
}
/// The default box 3d type with no unit.
pub type Box3D<T> = TypedBox3D<T, UnknownUnit>;
impl<T: Hash, U> Hash for TypedBox3D<T, U> {
impl<T: Hash, U> Hash for Box3D<T, U> {
fn hash<H: Hasher>(&self, h: &mut H) {
self.min.hash(h);
self.max.hash(h);
}
}
impl<T: Copy, U> Copy for TypedBox3D<T, U> {}
impl<T: Copy, U> Copy for Box3D<T, U> {}
impl<T: Copy, U> Clone for TypedBox3D<T, U> {
impl<T: Copy, U> Clone for Box3D<T, U> {
fn clone(&self) -> Self {
*self
}
}
impl<T: PartialEq, U> PartialEq<TypedBox3D<T, U>> for TypedBox3D<T, U> {
impl<T: PartialEq, U> PartialEq<Box3D<T, U>> for Box3D<T, U> {
fn eq(&self, other: &Self) -> bool {
self.min.eq(&other.min) && self.max.eq(&other.max)
}
}
impl<T: Eq, U> Eq for TypedBox3D<T, U> {}
impl<T: Eq, U> Eq for Box3D<T, U> {}
impl<T: fmt::Debug, U> fmt::Debug for TypedBox3D<T, U> {
impl<T: fmt::Debug, U> fmt::Debug for Box3D<T, U> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "TypedBox3D({:?}, {:?})", self.min, self.max)
write!(f, "Box3D({:?}, {:?})", self.min, self.max)
}
}
impl<T: fmt::Display, U> fmt::Display for TypedBox3D<T, U> {
impl<T: fmt::Display, U> fmt::Display for Box3D<T, U> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "Box3D({}, {})", self.min, self.max)
}
}
impl<T, U> TypedBox3D<T, U> {
impl<T, U> Box3D<T, U> {
/// Constructor.
pub fn new(min: TypedPoint3D<T, U>, max: TypedPoint3D<T, U>) -> Self {
TypedBox3D {
pub fn new(min: Point3D<T, U>, max: Point3D<T, U>) -> Self {
Box3D {
min,
max,
}
}
}
impl<T, U> TypedBox3D<T, U>
impl<T, U> Box3D<T, U>
where
T: Copy + Zero + PartialOrd,
{
/// Creates a Box3D of the given size, at offset zero.
#[inline]
pub fn from_size(size: TypedSize3D<T, U>) -> Self {
let zero = TypedPoint3D::zero();
pub fn from_size(size: Size3D<T, U>) -> Self {
let zero = Point3D::zero();
let point = size.to_vector().to_point();
TypedBox3D::from_points(&[zero, point])
Box3D::from_points(&[zero, point])
}
}
impl<T, U> TypedBox3D<T, U>
impl<T, U> Box3D<T, U>
where
T: Copy + PartialOrd,
{
@ -116,6 +113,14 @@ where
self.max.x <= self.min.x || self.max.y <= self.min.y || self.max.z <= self.min.z
}
#[inline]
pub fn to_non_empty(&self) -> Option<NonEmpty<Self>> {
if self.is_empty_or_negative() {
return None;
}
Some(NonEmpty(*self))
}
#[inline]
pub fn intersects(&self, other: &Self) -> bool {
@ -128,47 +133,50 @@ where
}
#[inline]
pub fn try_intersection(&self, other: &Self) -> Option<Self> {
pub fn try_intersection(&self, other: &Self) -> Option<NonEmpty<Self>> {
if !self.intersects(other) {
return None;
}
Some(self.intersection(other))
Some(NonEmpty(self.intersection(other)))
}
pub fn intersection(&self, other: &Self) -> Self {
let intersection_min = TypedPoint3D::new(
let intersection_min = Point3D::new(
max(self.min.x, other.min.x),
max(self.min.y, other.min.y),
max(self.min.z, other.min.z),
);
let intersection_max = TypedPoint3D::new(
let intersection_max = Point3D::new(
min(self.max.x, other.max.x),
min(self.max.y, other.max.y),
min(self.max.z, other.max.z),
);
TypedBox3D::new(
Box3D::new(
intersection_min,
intersection_max,
)
}
}
impl<T, U> TypedBox3D<T, U>
impl<T, U> Box3D<T, U>
where
T: Copy + Add<T, Output = T>,
{
/// Returns the same box3d, translated by a vector.
#[inline]
#[cfg_attr(feature = "unstable", must_use)]
pub fn translate(&self, by: &TypedVector3D<T, U>) -> Self {
Self::new(self.min + *by, self.max + *by)
#[must_use]
pub fn translate(&self, by: Vector3D<T, U>) -> Self {
Box3D {
min: self.min + by,
max: self.max + by,
}
}
}
impl<T, U> TypedBox3D<T, U>
impl<T, U> Box3D<T, U>
where
T: Copy + PartialOrd + Zero,
{
@ -176,14 +184,14 @@ where
/// in the box3d if they are on the front, left or top faces, but outside if they
/// are on the back, right or bottom faces.
#[inline]
pub fn contains(&self, other: &TypedPoint3D<T, U>) -> bool {
pub fn contains(&self, other: Point3D<T, U>) -> bool {
self.min.x <= other.x && other.x < self.max.x
&& self.min.y <= other.y && other.y < self.max.y
&& self.min.z <= other.z && other.z < self.max.z
}
}
impl<T, U> TypedBox3D<T, U>
impl<T, U> Box3D<T, U>
where
T: Copy + PartialOrd + Zero + Sub<T, Output = T>,
{
@ -199,13 +207,13 @@ where
}
}
impl<T, U> TypedBox3D<T, U>
impl<T, U> Box3D<T, U>
where
T: Copy + Sub<T, Output = T>,
{
#[inline]
pub fn size(&self)-> TypedSize3D<T, U> {
TypedSize3D::new(
pub fn size(&self)-> Size3D<T, U> {
Size3D::new(
self.max.x - self.min.x,
self.max.y - self.min.y,
self.max.z - self.min.z,
@ -213,28 +221,22 @@ where
}
}
impl<T, U> TypedBox3D<T, U>
impl<T, U> Box3D<T, U>
where
T: Copy + PartialEq + Add<T, Output = T> + Sub<T, Output = T>,
{
/// Inflates the box by the specified sizes on each side respectively.
#[inline]
#[cfg_attr(feature = "unstable", must_use)]
#[must_use]
pub fn inflate(&self, width: T, height: T, depth: T) -> Self {
TypedBox3D::new(
TypedPoint3D::new(self.min.x - width, self.min.y - height, self.min.z - depth),
TypedPoint3D::new(self.max.x + width, self.max.y + height, self.max.z + depth),
Box3D::new(
Point3D::new(self.min.x - width, self.min.y - height, self.min.z - depth),
Point3D::new(self.max.x + width, self.max.y + height, self.max.z + depth),
)
}
#[inline]
#[cfg_attr(feature = "unstable", must_use)]
pub fn inflate_typed(&self, width: Length<T, U>, height: Length<T, U>, depth: Length<T, U>) -> Self {
self.inflate(width.get(), height.get(), depth.get())
}
}
impl<T, U> TypedBox3D<T, U>
impl<T, U> Box3D<T, U>
where
T: Copy + Zero + PartialOrd,
{
@ -242,14 +244,14 @@ where
pub fn from_points<I>(points: I) -> Self
where
I: IntoIterator,
I::Item: Borrow<TypedPoint3D<T, U>>,
I::Item: Borrow<Point3D<T, U>>,
{
let mut points = points.into_iter();
// Need at least 2 different points for a valid box3d (ie: volume > 0).
let (mut min_x, mut min_y, mut min_z) = match points.next() {
Some(first) => (first.borrow().x, first.borrow().y, first.borrow().z),
None => return TypedBox3D::zero(),
None => return Box3D::zero(),
};
let (mut max_x, mut max_y, mut max_z) = (min_x, min_y, min_z);
@ -278,7 +280,7 @@ where
match points.next() {
Some(second) => assign_min_max(second),
None => return TypedBox3D::zero(),
None => return Box3D::zero(),
}
for point in points {
@ -286,11 +288,11 @@ where
}
}
Self::new(TypedPoint3D::new(min_x, min_y, min_z), TypedPoint3D::new(max_x, max_y, max_z))
Self::new(Point3D::new(min_x, min_y, min_z), Point3D::new(max_x, max_y, max_z))
}
}
impl<T, U> TypedBox3D<T, U>
impl<T, U> Box3D<T, U>
where
T: Copy + One + Add<Output = T> + Sub<Output = T> + Mul<Output = T>,
{
@ -306,29 +308,29 @@ where
}
}
impl<T, U> TypedBox3D<T, U>
impl<T, U> Box3D<T, U>
where
T: Copy + One + Add<Output = T> + Div<Output = T>,
{
pub fn center(&self) -> TypedPoint3D<T, U> {
pub fn center(&self) -> Point3D<T, U> {
let two = T::one() + T::one();
(self.min + self.max.to_vector()) / two
}
}
impl<T, U> TypedBox3D<T, U>
impl<T, U> Box3D<T, U>
where
T: Copy + Clone + PartialOrd + Add<T, Output = T> + Sub<T, Output = T> + Zero,
{
#[inline]
pub fn union(&self, other: &Self) -> Self {
TypedBox3D::new(
TypedPoint3D::new(
Box3D::new(
Point3D::new(
min(self.min.x, other.min.x),
min(self.min.y, other.min.y),
min(self.min.z, other.min.z),
),
TypedPoint3D::new(
Point3D::new(
max(self.max.x, other.max.x),
max(self.max.y, other.max.y),
max(self.max.z, other.max.z),
@ -337,7 +339,7 @@ where
}
}
impl<T, U> TypedBox3D<T, U>
impl<T, U> Box3D<T, U>
where
T: Copy,
{
@ -346,14 +348,14 @@ where
where
T: Mul<S, Output = T>
{
TypedBox3D::new(
TypedPoint3D::new(self.min.x * x, self.min.y * y, self.min.z * z),
TypedPoint3D::new(self.max.x * x, self.max.y * y, self.max.z * z),
Box3D::new(
Point3D::new(self.min.x * x, self.min.y * y, self.min.z * z),
Point3D::new(self.max.x * x, self.max.y * y, self.max.z * z),
)
}
}
impl<T, U> TypedBox3D<T, U>
impl<T, U> Box3D<T, U>
where
T: Copy + Mul<T, Output = T> + Sub<T, Output = T>,
{
@ -382,17 +384,17 @@ where
}
}
impl<T, U> TypedBox3D<T, U>
impl<T, U> Box3D<T, U>
where
T: Copy + Zero,
{
/// Constructor, setting all sides to zero.
pub fn zero() -> Self {
TypedBox3D::new(TypedPoint3D::zero(), TypedPoint3D::zero())
Box3D::new(Point3D::zero(), Point3D::zero())
}
}
impl<T, U> TypedBox3D<T, U>
impl<T, U> Box3D<T, U>
where
T: PartialEq,
{
@ -403,69 +405,74 @@ where
}
}
impl<T, U> Mul<T> for TypedBox3D<T, U>
impl<T, U> Mul<T> for Box3D<T, U>
where
T: Copy + Mul<T, Output = T>,
{
type Output = Self;
#[inline]
fn mul(self, scale: T) -> Self {
TypedBox3D::new(self.min * scale, self.max * scale)
Box3D::new(self.min * scale, self.max * scale)
}
}
impl<T, U> Div<T> for TypedBox3D<T, U>
impl<T, U> Div<T> for Box3D<T, U>
where
T: Copy + Div<T, Output = T>,
{
type Output = Self;
#[inline]
fn div(self, scale: T) -> Self {
TypedBox3D::new(self.min / scale, self.max / scale)
Box3D::new(self.min / scale, self.max / scale)
}
}
impl<T, U1, U2> Mul<TypedScale<T, U1, U2>> for TypedBox3D<T, U1>
impl<T, U1, U2> Mul<Scale<T, U1, U2>> for Box3D<T, U1>
where
T: Copy + Mul<T, Output = T>,
{
type Output = TypedBox3D<T, U2>;
type Output = Box3D<T, U2>;
#[inline]
fn mul(self, scale: TypedScale<T, U1, U2>) -> TypedBox3D<T, U2> {
TypedBox3D::new(self.min * scale, self.max * scale)
fn mul(self, scale: Scale<T, U1, U2>) -> Box3D<T, U2> {
Box3D::new(self.min * scale, self.max * scale)
}
}
impl<T, U1, U2> Div<TypedScale<T, U1, U2>> for TypedBox3D<T, U2>
impl<T, U1, U2> Div<Scale<T, U1, U2>> for Box3D<T, U2>
where
T: Copy + Div<T, Output = T>,
{
type Output = TypedBox3D<T, U1>;
type Output = Box3D<T, U1>;
#[inline]
fn div(self, scale: TypedScale<T, U1, U2>) -> TypedBox3D<T, U1> {
TypedBox3D::new(self.min / scale, self.max / scale)
fn div(self, scale: Scale<T, U1, U2>) -> Box3D<T, U1> {
Box3D::new(self.min / scale, self.max / scale)
}
}
impl<T, Unit> TypedBox3D<T, Unit>
impl<T, Unit> Box3D<T, Unit>
where
T: Copy,
{
/// Drop the units, preserving only the numeric value.
pub fn to_untyped(&self) -> Box3D<T> {
TypedBox3D::new(self.min.to_untyped(), self.max.to_untyped())
#[inline]
pub fn to_untyped(&self) -> Box3D<T, UnknownUnit> {
Box3D {
min: self.min.to_untyped(),
max: self.max.to_untyped(),
}
}
/// Tag a unitless value with units.
pub fn from_untyped(c: &Box3D<T>) -> TypedBox3D<T, Unit> {
TypedBox3D::new(
TypedPoint3D::from_untyped(&c.min),
TypedPoint3D::from_untyped(&c.max),
)
#[inline]
pub fn from_untyped(c: &Box3D<T, UnknownUnit>) -> Box3D<T, Unit> {
Box3D {
min: Point3D::from_untyped(c.min),
max: Point3D::from_untyped(c.max),
}
}
}
impl<T0, Unit> TypedBox3D<T0, Unit>
impl<T0, Unit> Box3D<T0, Unit>
where
T0: NumCast + Copy,
{
@ -474,8 +481,8 @@ where
/// 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(), round_in or round_out() before casting.
pub fn cast<T1: NumCast + Copy>(&self) -> TypedBox3D<T1, Unit> {
TypedBox3D::new(
pub fn cast<T1: NumCast + Copy>(&self) -> Box3D<T1, Unit> {
Box3D::new(
self.min.cast(),
self.max.cast(),
)
@ -486,15 +493,15 @@ where
/// 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(), round_in or round_out() before casting.
pub fn try_cast<T1: NumCast + Copy>(&self) -> Option<TypedBox3D<T1, Unit>> {
pub fn try_cast<T1: NumCast + Copy>(&self) -> Option<Box3D<T1, Unit>> {
match (self.min.try_cast(), self.max.try_cast()) {
(Some(a), Some(b)) => Some(TypedBox3D::new(a, b)),
(Some(a), Some(b)) => Some(Box3D::new(a, b)),
_ => None,
}
}
}
impl<T, U> TypedBox3D<T, U>
impl<T, U> Box3D<T, U>
where
T: Round,
{
@ -507,21 +514,21 @@ where
/// avoid pixel rounding errors.
/// Note that this is *not* rounding to nearest integer if the values are negative.
/// They are always rounding as floor(n + 0.5).
#[cfg_attr(feature = "unstable", must_use)]
#[must_use]
pub fn round(&self) -> Self {
TypedBox3D::new(self.min.round(), self.max.round())
Box3D::new(self.min.round(), self.max.round())
}
}
impl<T, U> TypedBox3D<T, U>
impl<T, U> Box3D<T, U>
where
T: Floor + Ceil,
{
/// Return a box3d with faces/edges rounded to integer coordinates, such that
/// the original box3d contains the resulting box3d.
#[cfg_attr(feature = "unstable", must_use)]
#[must_use]
pub fn round_in(&self) -> Self {
TypedBox3D {
Box3D {
min: self.min.ceil(),
max: self.max.floor(),
}
@ -529,9 +536,9 @@ where
/// Return a box3d with faces/edges rounded to integer coordinates, such that
/// the original box3d is contained in the resulting box3d.
#[cfg_attr(feature = "unstable", must_use)]
#[must_use]
pub fn round_out(&self) -> Self {
TypedBox3D {
Box3D {
min: self.min.floor(),
max: self.max.ceil(),
}
@ -539,14 +546,14 @@ where
}
// Convenience functions for common casts
impl<T: NumCast + Copy, Unit> TypedBox3D<T, Unit> {
impl<T: NumCast + Copy, Unit> Box3D<T, Unit> {
/// Cast into an `f32` box3d.
pub fn to_f32(&self) -> TypedBox3D<f32, Unit> {
pub fn to_f32(&self) -> Box3D<f32, Unit> {
self.cast()
}
/// Cast into an `f64` box3d.
pub fn to_f64(&self) -> TypedBox3D<f64, Unit> {
pub fn to_f64(&self) -> Box3D<f64, Unit> {
self.cast()
}
@ -555,7 +562,7 @@ impl<T: NumCast + Copy, Unit> TypedBox3D<T, Unit> {
/// When casting from floating point cuboids, it is worth considering whether
/// to `round()`, `round_in()` or `round_out()` before the cast in order to
/// obtain the desired conversion behavior.
pub fn to_usize(&self) -> TypedBox3D<usize, Unit> {
pub fn to_usize(&self) -> Box3D<usize, Unit> {
self.cast()
}
@ -564,7 +571,7 @@ impl<T: NumCast + Copy, Unit> TypedBox3D<T, Unit> {
/// When casting from floating point cuboids, it is worth considering whether
/// to `round()`, `round_in()` or `round_out()` before the cast in order to
/// obtain the desired conversion behavior.
pub fn to_u32(&self) -> TypedBox3D<u32, Unit> {
pub fn to_u32(&self) -> Box3D<u32, Unit> {
self.cast()
}
@ -573,7 +580,7 @@ impl<T: NumCast + Copy, Unit> TypedBox3D<T, Unit> {
/// When casting from floating point cuboids, it is worth considering whether
/// to `round()`, `round_in()` or `round_out()` before the cast in order to
/// obtain the desired conversion behavior.
pub fn to_i32(&self) -> TypedBox3D<i32, Unit> {
pub fn to_i32(&self) -> Box3D<i32, Unit> {
self.cast()
}
@ -582,31 +589,29 @@ impl<T: NumCast + Copy, Unit> TypedBox3D<T, Unit> {
/// When casting from floating point cuboids, it is worth considering whether
/// to `round()`, `round_in()` or `round_out()` before the cast in order to
/// obtain the desired conversion behavior.
pub fn to_i64(&self) -> TypedBox3D<i64, Unit> {
pub fn to_i64(&self) -> Box3D<i64, Unit> {
self.cast()
}
}
impl<T, U> From<TypedSize3D<T, U>> for TypedBox3D<T, U>
impl<T, U> From<Size3D<T, U>> for Box3D<T, U>
where
T: Copy + Zero + PartialOrd,
{
fn from(b: TypedSize3D<T, U>) -> Self {
fn from(b: Size3D<T, U>) -> Self {
Self::from_size(b)
}
}
/// Shorthand for `TypedBox3D::new(TypedPoint3D::new(x1, y1, z1), TypedPoint3D::new(x2, y2, z2))`.
pub fn box3d<T: Copy, U>(min_x: T, min_y: T, min_z: T, max_x: T, max_y: T, max_z: T) -> TypedBox3D<T, U> {
TypedBox3D::new(TypedPoint3D::new(min_x, min_y, min_z), TypedPoint3D::new(max_x, max_y, max_z))
/// Shorthand for `Box3D::new(Point3D::new(x1, y1, z1), Point3D::new(x2, y2, z2))`.
pub fn box3d<T: Copy, U>(min_x: T, min_y: T, min_z: T, max_x: T, max_y: T, max_z: T) -> Box3D<T, U> {
Box3D::new(Point3D::new(min_x, min_y, min_z), Point3D::new(max_x, max_y, max_z))
}
#[cfg(test)]
mod tests {
use vector::vec3;
use size::size3;
use point::{point3, Point3D};
use super::*;
use {point3, size3, vec3};
use default::{Box3D, Point3D};
#[test]
fn test_new() {
@ -714,7 +719,7 @@ mod tests {
let b = Box3D::from_size(size);
assert!(b.center() == center);
let translation = vec3(10.0, 2.5, 9.5);
let b = b.translate(&translation);
let b = b.translate(translation);
center += translation;
assert!(b.center() == center);
assert!(b.max.x == 25.0);
@ -808,7 +813,7 @@ mod tests {
#[test]
fn test_contains() {
let b = Box3D::from_points(&[point3(-20.0, -20.0, -20.0), point3(20.0, 20.0, 20.0)]);
assert!(b.contains(&point3(-15.3, 10.5, 18.4)));
assert!(b.contains(point3(-15.3, 10.5, 18.4)));
}
#[test]

92
third_party/rust/euclid/src/homogen.rs поставляемый
Просмотреть файл

@ -7,18 +7,21 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use point::{TypedPoint2D, TypedPoint3D};
use vector::{TypedVector2D, TypedVector3D};
use point::{Point2D, Point3D};
use vector::{Vector2D, Vector3D};
use num::{One, Zero};
use core::fmt;
use core::marker::PhantomData;
use core::ops::Div;
use core::cmp::{Eq, PartialEq};
use core::hash::{Hash};
#[cfg(feature = "serde")]
use serde;
/// Homogeneous vector in 3D space.
#[derive(EuclidMatrix)]
#[repr(C)]
pub struct HomogeneousVector<T, U> {
pub x: T,
@ -29,6 +32,63 @@ pub struct HomogeneousVector<T, U> {
pub _unit: PhantomData<U>,
}
impl<T: Copy, U> Copy for HomogeneousVector<T, U> {}
impl<T: Clone, U> Clone for HomogeneousVector<T, U> {
fn clone(&self) -> Self {
HomogeneousVector {
x: self.x.clone(),
y: self.y.clone(),
z: self.z.clone(),
w: self.w.clone(),
_unit: PhantomData,
}
}
}
#[cfg(feature = "serde")]
impl<'de, T, U> serde::Deserialize<'de> for HomogeneousVector<T, U>
where T: serde::Deserialize<'de>
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: serde::Deserializer<'de>
{
let (x, y, z, w) = try!(serde::Deserialize::deserialize(deserializer));
Ok(HomogeneousVector { x, y, z, w, _unit: PhantomData })
}
}
#[cfg(feature = "serde")]
impl<T, U> serde::Serialize for HomogeneousVector<T, U>
where T: serde::Serialize
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: serde::Serializer
{
(&self.x, &self.y, &self.z, &self.w).serialize(serializer)
}
}
impl<T, U> Eq for HomogeneousVector<T, U> where T: Eq {}
impl<T, U> PartialEq for HomogeneousVector<T, U>
where T: PartialEq
{
fn eq(&self, other: &Self) -> bool {
self.x == other.x && self.y == other.y && self.z == other.z && self.w == other.w
}
}
impl<T, U> Hash for HomogeneousVector<T, U>
where T: Hash
{
fn hash<H: ::core::hash::Hasher>(&self, h: &mut H) {
self.x.hash(h);
self.y.hash(h);
self.z.hash(h);
self.w.hash(h);
}
}
impl<T, U> HomogeneousVector<T, U> {
/// Constructor taking scalar values directly.
@ -44,9 +104,9 @@ 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<TypedPoint2D<T, U>> {
pub fn to_point2d(&self) -> Option<Point2D<T, U>> {
if self.w > T::zero() {
Some(TypedPoint2D::new(self.x / self.w, self.y / self.w))
Some(Point2D::new(self.x / self.w, self.y / self.w))
} else {
None
}
@ -56,39 +116,39 @@ 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<TypedPoint3D<T, U>> {
pub fn to_point3d(&self) -> Option<Point3D<T, U>> {
if self.w > T::zero() {
Some(TypedPoint3D::new(self.x / self.w, self.y / self.w, self.z / self.w))
Some(Point3D::new(self.x / self.w, self.y / self.w, self.z / self.w))
} else {
None
}
}
}
impl<T: Zero, U> From<TypedVector2D<T, U>> for HomogeneousVector<T, U> {
impl<T: Zero, U> From<Vector2D<T, U>> for HomogeneousVector<T, U> {
#[inline]
fn from(v: TypedVector2D<T, U>) -> Self {
fn from(v: Vector2D<T, U>) -> Self {
HomogeneousVector::new(v.x, v.y, T::zero(), T::zero())
}
}
impl<T: Zero, U> From<TypedVector3D<T, U>> for HomogeneousVector<T, U> {
impl<T: Zero, U> From<Vector3D<T, U>> for HomogeneousVector<T, U> {
#[inline]
fn from(v: TypedVector3D<T, U>) -> Self {
fn from(v: Vector3D<T, U>) -> Self {
HomogeneousVector::new(v.x, v.y, v.z, T::zero())
}
}
impl<T: Zero + One, U> From<TypedPoint2D<T, U>> for HomogeneousVector<T, U> {
impl<T: Zero + One, U> From<Point2D<T, U>> for HomogeneousVector<T, U> {
#[inline]
fn from(p: TypedPoint2D<T, U>) -> Self {
fn from(p: Point2D<T, U>) -> Self {
HomogeneousVector::new(p.x, p.y, T::zero(), T::one())
}
}
impl<T: One, U> From<TypedPoint3D<T, U>> for HomogeneousVector<T, U> {
impl<T: One, U> From<Point3D<T, U>> for HomogeneousVector<T, U> {
#[inline]
fn from(p: TypedPoint3D<T, U>) -> Self {
fn from(p: Point3D<T, U>) -> Self {
HomogeneousVector::new(p.x, p.y, p.z, T::one())
}
}
@ -109,7 +169,7 @@ impl<T: fmt::Display, U> fmt::Display for HomogeneousVector<T, U> {
#[cfg(test)]
mod homogeneous {
use super::HomogeneousVector;
use point::{Point2D, Point3D};
use default::{Point2D, Point3D};
#[test]
fn roundtrip() {

34
third_party/rust/euclid/src/length.rs поставляемый
Просмотреть файл

@ -8,7 +8,7 @@
// except according to those terms.
//! A one-dimensional length, tagged with its units.
use scale::TypedScale;
use scale::Scale;
use num::Zero;
use num_traits::{NumCast, Saturating};
@ -30,10 +30,10 @@ use core::fmt;
/// expression that requires a different unit. It may be a type without values, such as an empty
/// enum.
///
/// You can multiply a `Length` by a `scale::TypedScale` to convert it from one unit to
/// another. See the [`TypedScale`] docs for an example.
/// You can multiply a `Length` by a `scale::Scale` to convert it from one unit to
/// another. See the [`Scale`] docs for an example.
///
/// [`TypedScale`]: struct.TypedScale.html
/// [`Scale`]: struct.Scale.html
#[repr(C)]
pub struct Length<T, Unit>(pub T, #[doc(hidden)] pub PhantomData<Unit>);
@ -141,10 +141,10 @@ impl<U, T: Clone + Saturating> Saturating for Length<T, U> {
// length / length
impl<Src, Dst, T: Clone + Div<T, Output = T>> Div<Length<T, Src>> for Length<T, Dst> {
type Output = TypedScale<T, Src, Dst>;
type Output = Scale<T, Src, Dst>;
#[inline]
fn div(self, other: Length<T, Src>) -> TypedScale<T, Src, Dst> {
TypedScale::new(self.get() / other.get())
fn div(self, other: Length<T, Src>) -> Scale<T, Src, Dst> {
Scale::new(self.get() / other.get())
}
}
@ -183,19 +183,19 @@ impl<T: Copy + Div<T, Output = T>, U> DivAssign<T> for Length<T, U> {
}
// length * scaleFactor
impl<Src, Dst, T: Clone + Mul<T, Output = T>> Mul<TypedScale<T, Src, Dst>> for Length<T, Src> {
impl<Src, Dst, T: Clone + Mul<T, Output = T>> Mul<Scale<T, Src, Dst>> for Length<T, Src> {
type Output = Length<T, Dst>;
#[inline]
fn mul(self, scale: TypedScale<T, Src, Dst>) -> Length<T, Dst> {
fn mul(self, scale: Scale<T, Src, Dst>) -> Length<T, Dst> {
Length::new(self.get() * scale.get())
}
}
// length / scaleFactor
impl<Src, Dst, T: Clone + Div<T, Output = T>> Div<TypedScale<T, Src, Dst>> for Length<T, Dst> {
impl<Src, Dst, T: Clone + Div<T, Output = T>> Div<Scale<T, Src, Dst>> for Length<T, Dst> {
type Output = Length<T, Src>;
#[inline]
fn div(self, scale: TypedScale<T, Src, Dst>) -> Length<T, Src> {
fn div(self, scale: Scale<T, Src, Dst>) -> Length<T, Src> {
Length::new(self.get() / scale.get())
}
}
@ -267,7 +267,7 @@ mod tests {
use num::Zero;
use num_traits::Saturating;
use scale::TypedScale;
use scale::Scale;
use core::f32::INFINITY;
enum Inch {}
@ -379,21 +379,21 @@ mod tests {
#[test]
fn test_division_by_length() {
// Division results in a TypedScale from denominator units
// Division results in a Scale from denominator units
// to numerator units.
let length: Length<f32, Cm> = Length::new(5.0);
let duration: Length<f32, Second> = Length::new(10.0);
let result = length / duration;
let expected: TypedScale<f32, Second, Cm> = TypedScale::new(0.5);
let expected: Scale<f32, Second, Cm> = Scale::new(0.5);
assert_eq!(result, expected);
}
#[test]
fn test_multiplication() {
let length_mm: Length<f32, Mm> = Length::new(10.0);
let cm_per_mm: TypedScale<f32, Mm, Cm> = TypedScale::new(0.1);
let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
let result = length_mm * cm_per_mm;
@ -424,7 +424,7 @@ mod tests {
#[test]
fn test_division_by_scalefactor() {
let length: Length<f32, Cm> = Length::new(5.0);
let cm_per_second: TypedScale<f32, Second, Cm> = TypedScale::new(10.0);
let cm_per_second: Scale<f32, Second, Cm> = Scale::new(10.0);
let result = length / cm_per_second;
@ -514,7 +514,7 @@ mod tests {
let result = length / length_zero;
let expected: TypedScale<f32, Cm, Cm> = TypedScale::new(INFINITY);
let expected: Scale<f32, Cm, Cm> = Scale::new(INFINITY);
assert_eq!(result, expected);
}
}

105
third_party/rust/euclid/src/lib.rs поставляемый
Просмотреть файл

@ -7,7 +7,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![cfg_attr(feature = "unstable", feature(fn_must_use))]
#![cfg_attr(not(test), no_std)]
//! A collection of strongly typed math tools for computer graphics with an inclination
@ -19,42 +18,26 @@
//! a screen-space position by a world-space vector and this can be expressed using
//! the generic Unit parameter.
//!
//! This unit system is not mandatory and all Typed* structures have an alias
//! This unit system is not mandatory and all * structures have an alias
//! with the default unit: `UnknownUnit`.
//! for example ```Point2D<T>``` is equivalent to ```TypedPoint2D<T, UnknownUnit>```.
//! for example ```Point2D<T>``` is equivalent to ```Point2D<T, UnknownUnit>```.
//! Client code typically creates a set of aliases for each type and doesn't need
//! to deal with the specifics of typed units further. For example:
//!
//! ```rust
//! use euclid::*;
//! pub struct ScreenSpace;
//! pub type ScreenPoint = TypedPoint2D<f32, ScreenSpace>;
//! pub type ScreenSize = TypedSize2D<f32, ScreenSpace>;
//! pub type ScreenPoint = Point2D<f32, ScreenSpace>;
//! pub type ScreenSize = Size2D<f32, ScreenSpace>;
//! pub struct WorldSpace;
//! pub type WorldPoint = TypedPoint3D<f32, WorldSpace>;
//! pub type ProjectionMatrix = TypedTransform3D<f32, WorldSpace, ScreenSpace>;
//! pub type WorldPoint = Point3D<f32, WorldSpace>;
//! pub type ProjectionMatrix = Transform3D<f32, WorldSpace, ScreenSpace>;
//! // etc...
//! ```
//!
//! All euclid types are marked `#[repr(C)]` in order to facilitate exposing them to
//! foreign function interfaces (provided the underlying scalar type is also `repr(C)`).
//!
//! Components are accessed in their scalar form by default for convenience, and most
//! types additionally implement strongly typed accessors which return typed ```Length``` wrappers.
//! For example:
//!
//! ```rust
//! # use euclid::*;
//! # pub struct WorldSpace;
//! # pub type WorldPoint = TypedPoint3D<f32, WorldSpace>;
//! let p = WorldPoint::new(0.0, 1.0, 1.0);
//! // p.x is an f32.
//! println!("p.x = {:?} ", p.x);
//! // p.x is a Length<f32, WorldSpace>.
//! println!("p.x_typed() = {:?} ", p.x_typed());
//! // Length::get returns the scalar value (f32).
//! assert_eq!(p.x, p.x_typed().get());
//! ```
#[cfg(feature = "serde")]
#[macro_use]
@ -62,31 +45,28 @@ extern crate serde;
#[cfg(feature = "mint")]
pub extern crate mint;
#[macro_use]
extern crate euclid_macros;
extern crate num_traits;
#[cfg(test)]
extern crate rand;
#[cfg(test)]
use std as core;
pub use box2d::{TypedBox2D, Box2D};
pub use box2d::Box2D;
pub use length::Length;
pub use scale::TypedScale;
pub use transform2d::{Transform2D, TypedTransform2D};
pub use transform3d::{Transform3D, TypedTransform3D};
pub use point::{Point2D, Point3D, TypedPoint2D, TypedPoint3D, point2, point3};
pub use vector::{TypedVector2D, TypedVector3D, Vector2D, Vector3D, vec2, vec3};
pub use scale::Scale;
pub use transform2d::Transform2D;
pub use transform3d::Transform3D;
pub use point::{Point2D, Point3D, point2, point3};
pub use vector::{Vector2D, Vector3D, vec2, vec3};
pub use vector::{BoolVector2D, BoolVector3D, bvec2, bvec3};
pub use homogen::HomogeneousVector;
pub use nonempty::NonEmpty;
pub use rect::{rect, Rect, TypedRect};
pub use rigid::{RigidTransform3D, TypedRigidTransform3D};
pub use box3d::{box3d, Box3D, TypedBox3D};
pub use translation::{TypedTranslation2D, TypedTranslation3D};
pub use rotation::{Angle, Rotation2D, Rotation3D, TypedRotation2D, TypedRotation3D};
pub use side_offsets::{SideOffsets2D, TypedSideOffsets2D};
pub use size::{Size2D, TypedSize2D, size2};
pub use rect::{rect, Rect};
pub use rigid::{RigidTransform3D};
pub use box3d::{box3d, Box3D};
pub use translation::{Translation2D, Translation3D};
pub use rotation::{Angle, Rotation2D, Rotation3D};
pub use side_offsets::SideOffsets2D;
pub use size::{Size2D, Size3D, size2, size3};
pub use trig::Trig;
#[macro_use]
@ -111,31 +91,30 @@ mod translation;
mod trig;
mod vector;
mod box3d;
mod nonempty;
/// The default unit.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct UnknownUnit;
/// Temporary alias to facilitate the transition to the new naming scheme
#[deprecated]
pub type Matrix2D<T> = Transform2D<T>;
/// Temporary alias to facilitate the transition to the new naming scheme
#[deprecated]
pub type TypedMatrix2D<T, Src, Dst> = TypedTransform2D<T, Src, Dst>;
/// Temporary alias to facilitate the transition to the new naming scheme
#[deprecated]
pub type Matrix4D<T> = Transform3D<T>;
/// Temporary alias to facilitate the transition to the new naming scheme
#[deprecated]
pub type TypedMatrix4D<T, Src, Dst> = TypedTransform3D<T, Src, Dst>;
/// Temporary alias to facilitate the transition to the new naming scheme
#[deprecated]
pub type ScaleFactor<T, Src, Dst> = TypedScale<T, Src, Dst>;
/// Temporary alias to facilitate the transition to the new naming scheme
#[deprecated]
pub use Angle as Radians;
pub mod default {
use super::UnknownUnit;
pub type Point2D<T> = super::Point2D<T, UnknownUnit>;
pub type Point3D<T> = super::Point3D<T, UnknownUnit>;
pub type Vector2D<T> = super::Vector2D<T, UnknownUnit>;
pub type Vector3D<T> = super::Vector3D<T, UnknownUnit>;
pub type HomogeneousVector<T> = super::HomogeneousVector<T, UnknownUnit>;
pub type Size2D<T> = super::Size2D<T, UnknownUnit>;
pub type Size3D<T> = super::Size3D<T, UnknownUnit>;
pub type Rect<T> = super::Rect<T, UnknownUnit>;
pub type Box2D<T> = super::Box2D<T, UnknownUnit>;
pub type Box3D<T> = super::Box3D<T, UnknownUnit>;
pub type SideOffsets2D<T> = super::SideOffsets2D<T, UnknownUnit>;
pub type Transform2D<T> = super::Transform2D<T, UnknownUnit, UnknownUnit>;
pub type Transform3D<T> = super::Transform3D<T, UnknownUnit, UnknownUnit>;
pub type Rotation2D<T> = super::Rotation2D<T, UnknownUnit, UnknownUnit>;
pub type Rotation3D<T> = super::Rotation3D<T, UnknownUnit, UnknownUnit>;
pub type Translation3D<T> = super::Translation3D<T, UnknownUnit, UnknownUnit>;
pub type Scale<T> = super::Scale<T, UnknownUnit, UnknownUnit>;
pub type RigidTransform3D<T> = super::RigidTransform3D<T, UnknownUnit, UnknownUnit>;
}

259
third_party/rust/euclid/src/nonempty.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,259 @@
use {Rect, Box2D, Box3D, Vector2D, Vector3D, size2, point2, point3};
use approxord::{min, max};
use num::Zero;
use core::ops::Deref;
use core::ops::{Add, Sub};
use core::cmp::{PartialEq};
#[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 + Clone + Zero + PartialOrd + PartialEq + Add<T, Output = T> + Sub<T, Output = T>,
{
#[inline]
pub fn union(&self, other: &NonEmpty<Rect<T, U>>) -> NonEmpty<Rect<T, U>> {
let origin = point2(
min(self.min_x(), other.min_x()),
min(self.min_y(), other.min_y()),
);
let lower_right_x = max(self.max_x(), other.max_x());
let lower_right_y = max(self.max_y(), other.max_y());
NonEmpty(Rect {
origin,
size: size2(
lower_right_x - origin.x,
lower_right_y - origin.y,
),
})
}
#[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: &NonEmpty<Box2D<T, U>>) -> NonEmpty<Box2D<T, U>> {
NonEmpty(Box2D {
min: point2(
min(self.min.x, other.min.x),
min(self.min.y, other.min.y),
),
max: point2(
max(self.max.x, other.max.x),
max(self.max.y, other.max.y),
),
})
}
/// 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: &NonEmpty<Box3D<T, U>>) -> NonEmpty<Box3D<T, U>> {
NonEmpty(Box3D {
min: point3(
min(self.min.x, other.min.x),
min(self.min.y, other.min.y),
min(self.min.z, other.min.z),
),
max: point3(
max(self.max.x, other.max.x),
max(self.max.y, other.max.y),
max(self.max.z, other.max.z),
),
})
}
/// 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 default;
// 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 default;
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 default;
use {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))));
}

467
third_party/rust/euclid/src/point.rs поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

403
third_party/rust/euclid/src/rect.rs поставляемый
Просмотреть файл

@ -8,19 +8,19 @@
// except according to those terms.
use super::UnknownUnit;
use length::Length;
use scale::TypedScale;
use scale::Scale;
use num::*;
use box2d::TypedBox2D;
use point::TypedPoint2D;
use vector::TypedVector2D;
use side_offsets::TypedSideOffsets2D;
use size::TypedSize2D;
use box2d::Box2D;
use point::Point2D;
use vector::Vector2D;
use side_offsets::SideOffsets2D;
use size::Size2D;
use approxord::{min, max};
use nonempty::NonEmpty;
use num_traits::NumCast;
#[cfg(feature = "serde")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde::{Deserialize, Serialize};
use core::borrow::Borrow;
use core::cmp::PartialOrd;
@ -31,100 +31,78 @@ use core::ops::{Add, Div, Mul, Sub, Range};
/// A 2d Rectangle optionally tagged with a unit.
#[repr(C)]
pub struct TypedRect<T, U = UnknownUnit> {
pub origin: TypedPoint2D<T, U>,
pub size: TypedSize2D<T, U>,
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(bound(serialize = "T: Serialize", deserialize = "T: Deserialize<'de>")))]
pub struct Rect<T, U> {
pub origin: Point2D<T, U>,
pub size: Size2D<T, U>,
}
/// The default rectangle type with no unit.
pub type Rect<T> = TypedRect<T, UnknownUnit>;
#[cfg(feature = "serde")]
impl<'de, T: Copy + Deserialize<'de>, U> Deserialize<'de> for TypedRect<T, U> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let (origin, size) = try!(Deserialize::deserialize(deserializer));
Ok(TypedRect::new(origin, size))
}
}
#[cfg(feature = "serde")]
impl<T: Serialize, U> Serialize for TypedRect<T, U> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
(&self.origin, &self.size).serialize(serializer)
}
}
impl<T: Hash, U> Hash for TypedRect<T, U> {
impl<T: Hash, U> Hash for Rect<T, U> {
fn hash<H: Hasher>(&self, h: &mut H) {
self.origin.hash(h);
self.size.hash(h);
}
}
impl<T: Copy, U> Copy for TypedRect<T, U> {}
impl<T: Copy, U> Copy for Rect<T, U> {}
impl<T: Copy, U> Clone for TypedRect<T, U> {
impl<T: Copy, U> Clone for Rect<T, U> {
fn clone(&self) -> Self {
*self
}
}
impl<T: PartialEq, U> PartialEq<TypedRect<T, U>> for TypedRect<T, U> {
impl<T: PartialEq, U> PartialEq<Rect<T, U>> for Rect<T, U> {
fn eq(&self, other: &Self) -> bool {
self.origin.eq(&other.origin) && self.size.eq(&other.size)
}
}
impl<T: Eq, U> Eq for TypedRect<T, U> {}
impl<T: Eq, U> Eq for Rect<T, U> {}
impl<T: fmt::Debug, U> fmt::Debug for TypedRect<T, U> {
impl<T: fmt::Debug, U> fmt::Debug for Rect<T, U> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "TypedRect({:?} at {:?})", self.size, self.origin)
write!(f, "Rect({:?} at {:?})", self.size, self.origin)
}
}
impl<T: fmt::Display, U> fmt::Display for TypedRect<T, U> {
impl<T: fmt::Display, U> fmt::Display for Rect<T, U> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "Rect({} at {})", self.size, self.origin)
}
}
impl<T: Default, U> Default for TypedRect<T, U> {
impl<T: Default, U> Default for Rect<T, U> {
fn default() -> Self {
TypedRect::new(Default::default(), Default::default())
Rect::new(Default::default(), Default::default())
}
}
impl<T, U> TypedRect<T, U> {
impl<T, U> Rect<T, U> {
/// Constructor.
pub fn new(origin: TypedPoint2D<T, U>, size: TypedSize2D<T, U>) -> Self {
TypedRect {
pub fn new(origin: Point2D<T, U>, size: Size2D<T, U>) -> Self {
Rect {
origin,
size,
}
}
}
impl<T, U> TypedRect<T, U>
impl<T, U> Rect<T, U>
where
T: Copy + Zero
{
/// Creates a rect of the given size, at offset zero.
pub fn from_size(size: TypedSize2D<T, U>) -> Self {
TypedRect {
origin: TypedPoint2D::zero(),
pub fn from_size(size: Size2D<T, U>) -> Self {
Rect {
origin: Point2D::zero(),
size,
}
}
}
impl<T, U> TypedRect<T, U>
impl<T, U> Rect<T, U>
where
T: Copy + Clone + Zero + PartialOrd + PartialEq + Add<T, Output = T> + Sub<T, Output = T>,
{
@ -136,6 +114,16 @@ where
&& other.origin.y < self.origin.y + self.size.height
}
#[inline]
pub fn min(&self) -> Point2D<T, U> {
self.origin
}
#[inline]
pub fn max(&self) -> Point2D<T, U> {
self.origin + self.size
}
#[inline]
pub fn max_x(&self) -> T {
self.origin.x + self.size.width
@ -156,26 +144,6 @@ where
self.origin.y
}
#[inline]
pub fn max_x_typed(&self) -> Length<T, U> {
Length::new(self.max_x())
}
#[inline]
pub fn min_x_typed(&self) -> Length<T, U> {
Length::new(self.min_x())
}
#[inline]
pub fn max_y_typed(&self) -> Length<T, U> {
Length::new(self.max_y())
}
#[inline]
pub fn min_y_typed(&self) -> Length<T, U> {
Length::new(self.min_y())
}
#[inline]
pub fn x_range(&self) -> Range<T> {
self.min_x()..self.max_x()
@ -192,31 +160,31 @@ where
return None;
}
let upper_left = TypedPoint2D::new(
let upper_left = Point2D::new(
max(self.min_x(), other.min_x()),
max(self.min_y(), other.min_y()),
);
let lower_right_x = min(self.max_x(), other.max_x());
let lower_right_y = min(self.max_y(), other.max_y());
Some(TypedRect::new(
Some(Rect::new(
upper_left,
TypedSize2D::new(lower_right_x - upper_left.x, lower_right_y - upper_left.y),
Size2D::new(lower_right_x - upper_left.x, lower_right_y - upper_left.y),
))
}
/// Returns the same rectangle, translated by a vector.
#[inline]
#[cfg_attr(feature = "unstable", must_use)]
pub fn translate(&self, by: &TypedVector2D<T, U>) -> Self {
Self::new(self.origin + *by, self.size)
#[must_use]
pub fn translate(&self, by: Vector2D<T, U>) -> Self {
Self::new(self.origin + by, self.size)
}
/// Returns true if this rectangle contains the point. Points are considered
/// in the rectangle if they are on the left or top edge, but outside if they
/// are on the right or bottom edge.
#[inline]
pub fn contains(&self, other: &TypedPoint2D<T, U>) -> bool {
pub fn contains(&self, other: Point2D<T, U>) -> bool {
self.origin.x <= other.x && other.x < self.origin.x + self.size.width
&& self.origin.y <= other.y && other.y < self.origin.y + self.size.height
}
@ -226,17 +194,17 @@ 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() && rect.max_y() <= self.max_y())
}
#[inline]
#[cfg_attr(feature = "unstable", must_use)]
#[must_use]
pub fn inflate(&self, width: T, height: T) -> Self {
TypedRect::new(
TypedPoint2D::new(self.origin.x - width, self.origin.y - height),
TypedSize2D::new(
Rect::new(
Point2D::new(self.origin.x - width, self.origin.y - height),
Size2D::new(
self.size.width + width + width,
self.size.height + height + height,
),
@ -244,51 +212,25 @@ where
}
#[inline]
#[cfg_attr(feature = "unstable", must_use)]
pub fn inflate_typed(&self, width: Length<T, U>, height: Length<T, U>) -> Self {
self.inflate(width.get(), height.get())
}
#[inline]
pub fn top_right(&self) -> TypedPoint2D<T, U> {
TypedPoint2D::new(self.max_x(), self.origin.y)
}
#[inline]
pub fn bottom_left(&self) -> TypedPoint2D<T, U> {
TypedPoint2D::new(self.origin.x, self.max_y())
}
#[inline]
pub fn bottom_right(&self) -> TypedPoint2D<T, U> {
TypedPoint2D::new(self.max_x(), self.max_y())
}
#[inline]
pub fn to_box2d(&self) -> TypedBox2D<T, U> {
TypedBox2D {
min: self.origin,
max: self.bottom_right(),
pub fn to_box2d(&self) -> Box2D<T, U> {
Box2D {
min: self.min(),
max: self.max(),
}
}
#[inline]
#[cfg_attr(feature = "unstable", must_use)]
pub fn translate_by_size(&self, size: &TypedSize2D<T, U>) -> Self {
self.translate(&size.to_vector())
}
/// Calculate the size and position of an inner rectangle.
///
/// Subtracts the side offsets from all sides. The horizontal and vertical
/// offsets must not be larger than the original side length.
pub fn inner_rect(&self, offsets: TypedSideOffsets2D<T, U>) -> Self {
let rect = TypedRect::new(
TypedPoint2D::new(
/// This method assumes y oriented downward.
pub fn inner_rect(&self, offsets: SideOffsets2D<T, U>) -> Self {
let rect = Rect::new(
Point2D::new(
self.origin.x + offsets.left,
self.origin.y + offsets.top
),
TypedSize2D::new(
Size2D::new(
self.size.width - offsets.horizontal(),
self.size.height - offsets.vertical()
)
@ -301,13 +243,14 @@ where
/// Calculate the size and position of an outer rectangle.
///
/// Add the offsets to all sides. The expanded rectangle is returned.
pub fn outer_rect(&self, offsets: TypedSideOffsets2D<T, U>) -> Self {
TypedRect::new(
TypedPoint2D::new(
/// This method assumes y oriented downward.
pub fn outer_rect(&self, offsets: SideOffsets2D<T, U>) -> Self {
Rect::new(
Point2D::new(
self.origin.x - offsets.left,
self.origin.y - offsets.top
),
TypedSize2D::new(
Size2D::new(
self.size.width + offsets.horizontal(),
self.size.height + offsets.vertical()
)
@ -326,13 +269,13 @@ where
pub fn from_points<I>(points: I) -> Self
where
I: IntoIterator,
I::Item: Borrow<TypedPoint2D<T, U>>,
I::Item: Borrow<Point2D<T, U>>,
{
let mut points = points.into_iter();
let (mut min_x, mut min_y) = match points.next() {
Some(first) => (first.borrow().x, first.borrow().y),
None => return TypedRect::zero(),
None => return Rect::zero(),
};
let (mut max_x, mut max_y) = (min_x, min_y);
@ -351,14 +294,14 @@ where
max_y = p.y
}
}
TypedRect::new(
TypedPoint2D::new(min_x, min_y),
TypedSize2D::new(max_x - min_x, max_y - min_y),
Rect::new(
Point2D::new(min_x, min_y),
Size2D::new(max_x - min_x, max_y - min_y),
)
}
}
impl<T, U> TypedRect<T, U>
impl<T, U> Rect<T, U>
where
T: Copy + One + Add<Output = T> + Sub<Output = T> + Mul<Output = T>,
{
@ -374,17 +317,17 @@ where
}
}
impl<T, U> TypedRect<T, U>
impl<T, U> Rect<T, U>
where
T: Copy + One + Add<Output = T> + Div<Output = T>,
{
pub fn center(&self) -> TypedPoint2D<T, U> {
pub fn center(&self) -> Point2D<T, U> {
let two = T::one() + T::one();
self.origin + self.size.to_vector() / two
}
}
impl<T, U> TypedRect<T, U>
impl<T, U> Rect<T, U>
where
T: Copy + Clone + PartialOrd + Add<T, Output = T> + Sub<T, Output = T> + Zero,
{
@ -397,7 +340,7 @@ where
return *self;
}
let upper_left = TypedPoint2D::new(
let upper_left = Point2D::new(
min(self.min_x(), other.min_x()),
min(self.min_y(), other.min_y()),
);
@ -405,37 +348,37 @@ where
let lower_right_x = max(self.max_x(), other.max_x());
let lower_right_y = max(self.max_y(), other.max_y());
TypedRect::new(
Rect::new(
upper_left,
TypedSize2D::new(lower_right_x - upper_left.x, lower_right_y - upper_left.y),
Size2D::new(lower_right_x - upper_left.x, lower_right_y - upper_left.y),
)
}
}
impl<T, U> TypedRect<T, U> {
impl<T, U> Rect<T, U> {
#[inline]
pub fn scale<S: Copy>(&self, x: S, y: S) -> Self
where
T: Copy + Clone + Mul<S, Output = T>,
{
TypedRect::new(
TypedPoint2D::new(self.origin.x * x, self.origin.y * y),
TypedSize2D::new(self.size.width * x, self.size.height * y),
Rect::new(
Point2D::new(self.origin.x * x, self.origin.y * y),
Size2D::new(self.size.width * x, self.size.height * y),
)
}
}
impl<T: Copy + Clone + Mul<T, Output = T>, U> TypedRect<T, U> {
impl<T: Copy + Clone + Mul<T, Output = T>, U> Rect<T, U> {
#[inline]
pub fn area(&self) -> T {
self.size.area()
}
}
impl<T: Copy + PartialEq + Zero, U> TypedRect<T, U> {
impl<T: Copy + PartialEq + Zero, U> Rect<T, U> {
/// Constructor, setting all sides to zero.
pub fn zero() -> Self {
TypedRect::new(TypedPoint2D::origin(), TypedSize2D::zero())
Rect::new(Point2D::origin(), Size2D::zero())
}
/// Returns true if the size is zero, regardless of the origin's value.
@ -444,61 +387,80 @@ impl<T: Copy + PartialEq + Zero, U> TypedRect<T, U> {
}
}
impl<T: Copy + Mul<T, Output = T>, U> Mul<T> for TypedRect<T, U> {
impl<T: Copy + Zero + PartialOrd, U> Rect<T, U> {
#[inline]
pub fn is_empty_or_negative(&self) -> bool {
self.size.is_empty_or_negative()
}
#[inline]
pub fn to_non_empty(&self) -> Option<NonEmpty<Self>> {
if self.is_empty_or_negative() {
return None;
}
Some(NonEmpty(*self))
}
}
impl<T: Copy + Mul<T, Output = T>, U> Mul<T> for Rect<T, U> {
type Output = Self;
#[inline]
fn mul(self, scale: T) -> Self {
TypedRect::new(self.origin * scale, self.size * scale)
Rect::new(self.origin * scale, self.size * scale)
}
}
impl<T: Copy + Div<T, Output = T>, U> Div<T> for TypedRect<T, U> {
impl<T: Copy + Div<T, Output = T>, U> Div<T> for Rect<T, U> {
type Output = Self;
#[inline]
fn div(self, scale: T) -> Self {
TypedRect::new(self.origin / scale, self.size / scale)
Rect::new(self.origin / scale, self.size / scale)
}
}
impl<T: Copy + Mul<T, Output = T>, U1, U2> Mul<TypedScale<T, U1, U2>> for TypedRect<T, U1> {
type Output = TypedRect<T, U2>;
impl<T: Copy + Mul<T, Output = T>, U1, U2> Mul<Scale<T, U1, U2>> for Rect<T, U1> {
type Output = Rect<T, U2>;
#[inline]
fn mul(self, scale: TypedScale<T, U1, U2>) -> TypedRect<T, U2> {
TypedRect::new(self.origin * scale, self.size * scale)
fn mul(self, scale: Scale<T, U1, U2>) -> Rect<T, U2> {
Rect::new(self.origin * scale, self.size * scale)
}
}
impl<T: Copy + Div<T, Output = T>, U1, U2> Div<TypedScale<T, U1, U2>> for TypedRect<T, U2> {
type Output = TypedRect<T, U1>;
impl<T: Copy + Div<T, Output = T>, U1, U2> Div<Scale<T, U1, U2>> for Rect<T, U2> {
type Output = Rect<T, U1>;
#[inline]
fn div(self, scale: TypedScale<T, U1, U2>) -> TypedRect<T, U1> {
TypedRect::new(self.origin / scale, self.size / scale)
fn div(self, scale: Scale<T, U1, U2>) -> Rect<T, U1> {
Rect::new(self.origin / scale, self.size / scale)
}
}
impl<T: Copy, Unit> TypedRect<T, Unit> {
impl<T: Copy, Unit> Rect<T, Unit> {
/// Drop the units, preserving only the numeric value.
pub fn to_untyped(&self) -> Rect<T> {
TypedRect::new(self.origin.to_untyped(), self.size.to_untyped())
#[inline]
pub fn to_untyped(&self) -> Rect<T, UnknownUnit> {
Rect::new(self.origin.to_untyped(), self.size.to_untyped())
}
/// Tag a unitless value with units.
pub fn from_untyped(r: &Rect<T>) -> TypedRect<T, Unit> {
TypedRect::new(
TypedPoint2D::from_untyped(&r.origin),
TypedSize2D::from_untyped(&r.size),
#[inline]
pub fn from_untyped(r: &Rect<T, UnknownUnit>) -> Rect<T, Unit> {
Rect::new(
Point2D::from_untyped(r.origin),
Size2D::from_untyped(r.size),
)
}
}
impl<T0: NumCast + Copy, Unit> TypedRect<T0, Unit> {
impl<T0: NumCast + Copy, Unit> Rect<T0, Unit> {
/// Cast from one numeric representation to another, preserving the units.
///
/// 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(), round_in or round_out() before casting.
pub fn cast<T1: NumCast + Copy>(&self) -> TypedRect<T1, Unit> {
TypedRect::new(
pub fn cast<T1: NumCast + Copy>(&self) -> Rect<T1, Unit> {
Rect::new(
self.origin.cast(),
self.size.cast(),
)
@ -509,15 +471,15 @@ impl<T0: NumCast + Copy, Unit> TypedRect<T0, Unit> {
/// 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(), round_in or round_out() before casting.
pub fn try_cast<T1: NumCast + Copy>(&self) -> Option<TypedRect<T1, Unit>> {
pub fn try_cast<T1: NumCast + Copy>(&self) -> Option<Rect<T1, Unit>> {
match (self.origin.try_cast(), self.size.try_cast()) {
(Some(origin), Some(size)) => Some(TypedRect::new(origin, size)),
(Some(origin), Some(size)) => Some(Rect::new(origin, size)),
_ => None,
}
}
}
impl<T: Floor + Ceil + Round + Add<T, Output = T> + Sub<T, Output = T>, U> TypedRect<T, U> {
impl<T: Floor + Ceil + Round + Add<T, Output = T> + Sub<T, Output = T>, U> Rect<T, U> {
/// Return a rectangle with edges rounded to integer coordinates, such that
/// the returned rectangle has the same set of pixel centers as the original
/// one.
@ -527,41 +489,41 @@ impl<T: Floor + Ceil + Round + Add<T, Output = T> + Sub<T, Output = T>, U> Typed
/// avoid pixel rounding errors.
/// Note that this is *not* rounding to nearest integer if the values are negative.
/// They are always rounding as floor(n + 0.5).
#[cfg_attr(feature = "unstable", must_use)]
#[must_use]
pub fn round(&self) -> Self {
let origin = self.origin.round();
let size = self.origin.add_size(&self.size).round() - origin;
TypedRect::new(origin, TypedSize2D::new(size.x, size.y))
Rect::new(origin, Size2D::new(size.x, size.y))
}
/// Return a rectangle with edges rounded to integer coordinates, such that
/// the original rectangle contains the resulting rectangle.
#[cfg_attr(feature = "unstable", must_use)]
#[must_use]
pub fn round_in(&self) -> Self {
let origin = self.origin.ceil();
let size = self.origin.add_size(&self.size).floor() - origin;
TypedRect::new(origin, TypedSize2D::new(size.x, size.y))
Rect::new(origin, Size2D::new(size.x, size.y))
}
/// Return a rectangle with edges rounded to integer coordinates, such that
/// the original rectangle is contained in the resulting rectangle.
#[cfg_attr(feature = "unstable", must_use)]
#[must_use]
pub fn round_out(&self) -> Self {
let origin = self.origin.floor();
let size = self.origin.add_size(&self.size).ceil() - origin;
TypedRect::new(origin, TypedSize2D::new(size.x, size.y))
Rect::new(origin, Size2D::new(size.x, size.y))
}
}
// Convenience functions for common casts
impl<T: NumCast + Copy, Unit> TypedRect<T, Unit> {
impl<T: NumCast + Copy, Unit> Rect<T, Unit> {
/// Cast into an `f32` rectangle.
pub fn to_f32(&self) -> TypedRect<f32, Unit> {
pub fn to_f32(&self) -> Rect<f32, Unit> {
self.cast()
}
/// Cast into an `f64` rectangle.
pub fn to_f64(&self) -> TypedRect<f64, Unit> {
pub fn to_f64(&self) -> Rect<f64, Unit> {
self.cast()
}
@ -570,7 +532,7 @@ impl<T: NumCast + Copy, Unit> TypedRect<T, Unit> {
/// When casting from floating point rectangles, it is worth considering whether
/// to `round()`, `round_in()` or `round_out()` before the cast in order to
/// obtain the desired conversion behavior.
pub fn to_usize(&self) -> TypedRect<usize, Unit> {
pub fn to_usize(&self) -> Rect<usize, Unit> {
self.cast()
}
@ -579,7 +541,7 @@ impl<T: NumCast + Copy, Unit> TypedRect<T, Unit> {
/// When casting from floating point rectangles, it is worth considering whether
/// to `round()`, `round_in()` or `round_out()` before the cast in order to
/// obtain the desired conversion behavior.
pub fn to_u32(&self) -> TypedRect<u32, Unit> {
pub fn to_u32(&self) -> Rect<u32, Unit> {
self.cast()
}
@ -588,7 +550,7 @@ impl<T: NumCast + Copy, Unit> TypedRect<T, Unit> {
/// When casting from floating point rectangles, it is worth considering whether
/// to `round()`, `round_in()` or `round_out()` before the cast in order to
/// obtain the desired conversion behavior.
pub fn to_i32(&self) -> TypedRect<i32, Unit> {
pub fn to_i32(&self) -> Rect<i32, Unit> {
self.cast()
}
@ -597,36 +559,34 @@ impl<T: NumCast + Copy, Unit> TypedRect<T, Unit> {
/// When casting from floating point rectangles, it is worth considering whether
/// to `round()`, `round_in()` or `round_out()` before the cast in order to
/// obtain the desired conversion behavior.
pub fn to_i64(&self) -> TypedRect<i64, Unit> {
pub fn to_i64(&self) -> Rect<i64, Unit> {
self.cast()
}
}
impl<T, U> From<TypedSize2D<T, U>> for TypedRect<T, U>
impl<T, U> From<Size2D<T, U>> for Rect<T, U>
where T: Copy + Zero
{
fn from(size: TypedSize2D<T, U>) -> Self {
fn from(size: Size2D<T, U>) -> Self {
Self::from_size(size)
}
}
/// Shorthand for `TypedRect::new(TypedPoint2D::new(x, y), TypedSize2D::new(w, h))`.
pub fn rect<T: Copy, U>(x: T, y: T, w: T, h: T) -> TypedRect<T, U> {
TypedRect::new(TypedPoint2D::new(x, y), TypedSize2D::new(w, h))
/// Shorthand for `Rect::new(Point2D::new(x, y), Size2D::new(w, h))`.
pub fn rect<T: Copy, U>(x: T, y: T, w: T, h: T) -> Rect<T, U> {
Rect::new(Point2D::new(x, y), Size2D::new(w, h))
}
#[cfg(test)]
mod tests {
use point::{Point2D, point2};
use vector::vec2;
use default::{Point2D, Rect, Size2D};
use {point2, vec2, rect, size2};
use side_offsets::SideOffsets2D;
use size::Size2D;
use super::*;
#[test]
fn test_translate() {
let p = Rect::new(Point2D::new(0u32, 0u32), Size2D::new(50u32, 40u32));
let pp = p.translate(&vec2(10, 15));
let pp = p.translate(vec2(10, 15));
assert!(pp.size.width == 50);
assert!(pp.size.height == 40);
@ -634,26 +594,7 @@ mod tests {
assert!(pp.origin.y == 15);
let r = Rect::new(Point2D::new(-10, -5), Size2D::new(50, 40));
let rr = r.translate(&vec2(0, -10));
assert!(rr.size.width == 50);
assert!(rr.size.height == 40);
assert!(rr.origin.x == -10);
assert!(rr.origin.y == -15);
}
#[test]
fn test_translate_by_size() {
let p = Rect::new(Point2D::new(0u32, 0u32), Size2D::new(50u32, 40u32));
let pp = p.translate_by_size(&Size2D::new(10, 15));
assert!(pp.size.width == 50);
assert!(pp.size.height == 40);
assert!(pp.origin.x == 10);
assert!(pp.origin.y == 15);
let r = Rect::new(Point2D::new(-10, -5), Size2D::new(50, 40));
let rr = r.translate_by_size(&Size2D::new(0, -10));
let rr = r.translate(vec2(0, -10));
assert!(rr.size.width == 50);
assert!(rr.size.height == 40);
@ -707,42 +648,42 @@ mod tests {
fn test_contains() {
let r = Rect::new(Point2D::new(-20, 15), Size2D::new(100, 200));
assert!(r.contains(&Point2D::new(0, 50)));
assert!(r.contains(&Point2D::new(-10, 200)));
assert!(r.contains(Point2D::new(0, 50)));
assert!(r.contains(Point2D::new(-10, 200)));
// The `contains` method is inclusive of the top/left edges, but not the
// bottom/right edges.
assert!(r.contains(&Point2D::new(-20, 15)));
assert!(!r.contains(&Point2D::new(80, 15)));
assert!(!r.contains(&Point2D::new(80, 215)));
assert!(!r.contains(&Point2D::new(-20, 215)));
assert!(r.contains(Point2D::new(-20, 15)));
assert!(!r.contains(Point2D::new(80, 15)));
assert!(!r.contains(Point2D::new(80, 215)));
assert!(!r.contains(Point2D::new(-20, 215)));
// Points beyond the top-left corner.
assert!(!r.contains(&Point2D::new(-25, 15)));
assert!(!r.contains(&Point2D::new(-15, 10)));
assert!(!r.contains(Point2D::new(-25, 15)));
assert!(!r.contains(Point2D::new(-15, 10)));
// Points beyond the top-right corner.
assert!(!r.contains(&Point2D::new(85, 20)));
assert!(!r.contains(&Point2D::new(75, 10)));
assert!(!r.contains(Point2D::new(85, 20)));
assert!(!r.contains(Point2D::new(75, 10)));
// Points beyond the bottom-right corner.
assert!(!r.contains(&Point2D::new(85, 210)));
assert!(!r.contains(&Point2D::new(75, 220)));
assert!(!r.contains(Point2D::new(85, 210)));
assert!(!r.contains(Point2D::new(75, 220)));
// Points beyond the bottom-left corner.
assert!(!r.contains(&Point2D::new(-25, 210)));
assert!(!r.contains(&Point2D::new(-15, 220)));
assert!(!r.contains(Point2D::new(-25, 210)));
assert!(!r.contains(Point2D::new(-15, 220)));
let r = Rect::new(Point2D::new(-20.0, 15.0), Size2D::new(100.0, 200.0));
assert!(r.contains_rect(&r));
assert!(!r.contains_rect(&r.translate(&vec2(0.1, 0.0))));
assert!(!r.contains_rect(&r.translate(&vec2(-0.1, 0.0))));
assert!(!r.contains_rect(&r.translate(&vec2(0.0, 0.1))));
assert!(!r.contains_rect(&r.translate(&vec2(0.0, -0.1))));
assert!(!r.contains_rect(&r.translate(vec2(0.1, 0.0))));
assert!(!r.contains_rect(&r.translate(vec2(-0.1, 0.0))));
assert!(!r.contains_rect(&r.translate(vec2(0.0, 0.1))));
assert!(!r.contains_rect(&r.translate(vec2(0.0, -0.1))));
// Empty rectangles are always considered as contained in other rectangles,
// even if their origin is not.
let p = Point2D::new(1.0, 1.0);
assert!(!r.contains(&p));
assert!(!r.contains(p));
assert!(r.contains_rect(&Rect::new(p, Size2D::zero())));
}
@ -786,7 +727,7 @@ mod tests {
#[test]
fn test_inner_outer_rect() {
let inner_rect: Rect<i32> = Rect::new(Point2D::new(20, 40), Size2D::new(80, 100));
let inner_rect = Rect::new(point2(20, 40), size2(80, 100));
let offsets = SideOffsets2D::new(20, 10, 10, 10);
let outer_rect = inner_rect.outer_rect(offsets);
assert_eq!(outer_rect.origin.x, 10);

94
third_party/rust/euclid/src/rigid.rs поставляемый
Просмотреть файл

@ -1,7 +1,7 @@
use approxeq::ApproxEq;
use num_traits::Float;
use trig::Trig;
use {TypedRotation3D, TypedTransform3D, TypedVector3D, UnknownUnit};
use {Rotation3D, Transform3D, Vector3D};
/// A rigid transformation. All lengths are preserved under such a transformation.
///
@ -14,21 +14,19 @@ use {TypedRotation3D, TypedTransform3D, TypedVector3D, UnknownUnit};
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[repr(C)]
pub struct TypedRigidTransform3D<T, Src, Dst> {
pub rotation: TypedRotation3D<T, Src, Dst>,
pub translation: TypedVector3D<T, Dst>,
pub struct RigidTransform3D<T, Src, Dst> {
pub rotation: Rotation3D<T, Src, Dst>,
pub translation: Vector3D<T, Dst>,
}
pub type RigidTransform3D<T> = TypedRigidTransform3D<T, UnknownUnit, UnknownUnit>;
// All matrix multiplication in this file is in row-vector notation,
// i.e. a vector `v` is transformed with `v * T`, and if you want to apply `T1`
// before `T2` you use `T1 * T2`
impl<T: Float + ApproxEq<T>, Src, Dst> TypedRigidTransform3D<T, Src, Dst> {
impl<T: Float + ApproxEq<T>, Src, Dst> RigidTransform3D<T, Src, Dst> {
/// Construct a new rigid transformation, where the `rotation` applies first
#[inline]
pub fn new(rotation: TypedRotation3D<T, Src, Dst>, translation: TypedVector3D<T, Dst>) -> Self {
pub fn new(rotation: Rotation3D<T, Src, Dst>, translation: Vector3D<T, Dst>) -> Self {
Self {
rotation,
translation,
@ -39,16 +37,16 @@ impl<T: Float + ApproxEq<T>, Src, Dst> TypedRigidTransform3D<T, Src, Dst> {
#[inline]
pub fn identity() -> Self {
Self {
rotation: TypedRotation3D::identity(),
translation: TypedVector3D::zero(),
rotation: Rotation3D::identity(),
translation: Vector3D::zero(),
}
}
/// Construct a new rigid transformation, where the `translation` applies first
#[inline]
pub fn new_from_reversed(
translation: TypedVector3D<T, Src>,
rotation: TypedRotation3D<T, Src, Dst>,
translation: Vector3D<T, Src>,
rotation: Rotation3D<T, Src, Dst>,
) -> Self {
// T * R
// = (R * R^-1) * T * R
@ -59,7 +57,7 @@ impl<T: Float + ApproxEq<T>, Src, Dst> TypedRigidTransform3D<T, Src, Dst> {
// It is equivalent to the translation matrix obtained by rotating the
// translation by R
let translation = rotation.rotate_vector3d(&translation);
let translation = rotation.transform_vector3d(translation);
Self {
rotation,
translation,
@ -67,18 +65,18 @@ impl<T: Float + ApproxEq<T>, Src, Dst> TypedRigidTransform3D<T, Src, Dst> {
}
#[inline]
pub fn from_rotation(rotation: TypedRotation3D<T, Src, Dst>) -> Self {
pub fn from_rotation(rotation: Rotation3D<T, Src, Dst>) -> Self {
Self {
rotation,
translation: TypedVector3D::zero(),
translation: Vector3D::zero(),
}
}
#[inline]
pub fn from_translation(translation: TypedVector3D<T, Dst>) -> Self {
pub fn from_translation(translation: Vector3D<T, Dst>) -> Self {
Self {
translation,
rotation: TypedRotation3D::identity(),
rotation: Rotation3D::identity(),
}
}
@ -86,7 +84,7 @@ impl<T: Float + ApproxEq<T>, Src, Dst> TypedRigidTransform3D<T, Src, Dst> {
///
/// i.e., the translation is applied _first_
#[inline]
pub fn decompose_reversed(&self) -> (TypedVector3D<T, Src>, TypedRotation3D<T, Src, Dst>) {
pub fn decompose_reversed(&self) -> (Vector3D<T, Src>, Rotation3D<T, Src, Dst>) {
// self = R * T
// = R * T * (R^-1 * R)
// = (R * T * R^-1) * R)
@ -94,7 +92,7 @@ impl<T: Float + ApproxEq<T>, Src, Dst> TypedRigidTransform3D<T, Src, Dst> {
//
// T' = (R^ * T * R^-1) is T rotated by R^-1
let translation = self.rotation.inverse().rotate_vector3d(&self.translation);
let translation = self.rotation.inverse().transform_vector3d(self.translation);
(translation, self.rotation)
}
@ -103,10 +101,10 @@ impl<T: Float + ApproxEq<T>, Src, Dst> TypedRigidTransform3D<T, Src, Dst> {
///
/// i.e., this produces `self * other` in row-vector notation
#[inline]
pub fn post_mul<Dst2>(
pub fn post_transform<Dst2>(
&self,
other: &TypedRigidTransform3D<T, Dst, Dst2>,
) -> TypedRigidTransform3D<T, Src, Dst2> {
other: &RigidTransform3D<T, Dst, Dst2>,
) -> RigidTransform3D<T, Src, Dst2> {
// self = R1 * T1
// other = R2 * T2
// result = R1 * T1 * R2 * T2
@ -121,10 +119,10 @@ impl<T: Float + ApproxEq<T>, Src, Dst> TypedRigidTransform3D<T, Src, Dst> {
let t_prime = other
.rotation
.rotate_vector3d(&self.translation);
.transform_vector3d(self.translation);
let r_prime = self.rotation.post_rotate(&other.rotation);
let t_prime2 = t_prime + other.translation;
TypedRigidTransform3D {
RigidTransform3D {
rotation: r_prime,
translation: t_prime2,
}
@ -135,16 +133,16 @@ impl<T: Float + ApproxEq<T>, Src, Dst> TypedRigidTransform3D<T, Src, Dst> {
///
/// i.e., this produces `other * self` in row-vector notation
#[inline]
pub fn pre_mul<Src2>(
pub fn pre_transform<Src2>(
&self,
other: &TypedRigidTransform3D<T, Src2, Src>,
) -> TypedRigidTransform3D<T, Src2, Dst> {
other.post_mul(&self)
other: &RigidTransform3D<T, Src2, Src>,
) -> RigidTransform3D<T, Src2, Dst> {
other.post_transform(&self)
}
/// Inverts the transformation
#[inline]
pub fn inverse(&self) -> TypedRigidTransform3D<T, Dst, Src> {
pub fn inverse(&self) -> RigidTransform3D<T, Dst, Src> {
// result = (self)^-1
// = (R * T)^-1
// = T^-1 * R^-1
@ -157,34 +155,34 @@ impl<T: Float + ApproxEq<T>, Src, Dst> TypedRigidTransform3D<T, Src, Dst> {
//
// An easier way of writing this is to use new_from_reversed() with R^-1 and T^-1
TypedRigidTransform3D::new_from_reversed(
RigidTransform3D::new_from_reversed(
-self.translation,
self.rotation.inverse(),
)
}
pub fn to_transform(&self) -> TypedTransform3D<T, Src, Dst>
pub fn to_transform(&self) -> Transform3D<T, Src, Dst>
where
T: Trig,
{
self.translation
.to_transform()
.pre_mul(&self.rotation.to_transform())
.pre_transform(&self.rotation.to_transform())
}
}
impl<T: Float + ApproxEq<T>, Src, Dst> From<TypedRotation3D<T, Src, Dst>>
for TypedRigidTransform3D<T, Src, Dst>
impl<T: Float + ApproxEq<T>, Src, Dst> From<Rotation3D<T, Src, Dst>>
for RigidTransform3D<T, Src, Dst>
{
fn from(rot: TypedRotation3D<T, Src, Dst>) -> Self {
fn from(rot: Rotation3D<T, Src, Dst>) -> Self {
Self::from_rotation(rot)
}
}
impl<T: Float + ApproxEq<T>, Src, Dst> From<TypedVector3D<T, Dst>>
for TypedRigidTransform3D<T, Src, Dst>
impl<T: Float + ApproxEq<T>, Src, Dst> From<Vector3D<T, Dst>>
for RigidTransform3D<T, Src, Dst>
{
fn from(t: TypedVector3D<T, Dst>) -> Self {
fn from(t: Vector3D<T, Dst>) -> Self {
Self::from_translation(t)
}
}
@ -192,7 +190,7 @@ impl<T: Float + ApproxEq<T>, Src, Dst> From<TypedVector3D<T, Dst>>
#[cfg(test)]
mod test {
use super::RigidTransform3D;
use {Rotation3D, TypedTransform3D, Vector3D};
use default::{Rotation3D, Transform3D, Vector3D};
#[test]
fn test_rigid_construction() {
@ -202,13 +200,13 @@ mod test {
let rigid = RigidTransform3D::new(rotation, translation);
assert!(rigid
.to_transform()
.approx_eq(&translation.to_transform().pre_mul(&rotation.to_transform())));
.approx_eq(&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()
.post_mul(&rotation.to_transform())
.post_transform(&rotation.to_transform())
));
}
@ -221,7 +219,7 @@ mod test {
let (t2, r2) = rigid.decompose_reversed();
assert!(rigid
.to_transform()
.approx_eq(&t2.to_transform().post_mul(&r2.to_transform())));
.approx_eq(&t2.to_transform().post_transform(&r2.to_transform())));
}
#[test]
@ -232,9 +230,9 @@ mod test {
let rigid = RigidTransform3D::new(rotation, translation);
let inverse = rigid.inverse();
assert!(rigid
.post_mul(&inverse)
.post_transform(&inverse)
.to_transform()
.approx_eq(&TypedTransform3D::identity()));
.approx_eq(&Transform3D::identity()));
assert!(inverse
.to_transform()
.approx_eq(&rigid.to_transform().inverse().unwrap()));
@ -250,12 +248,12 @@ mod test {
let rigid2 = RigidTransform3D::new(rotation2, translation2);
assert!(rigid
.post_mul(&rigid2)
.post_transform(&rigid2)
.to_transform()
.approx_eq(&rigid.to_transform().post_mul(&rigid2.to_transform())));
.approx_eq(&rigid.to_transform().post_transform(&rigid2.to_transform())));
assert!(rigid
.pre_mul(&rigid2)
.pre_transform(&rigid2)
.to_transform()
.approx_eq(&rigid.to_transform().pre_mul(&rigid2.to_transform())));
.approx_eq(&rigid.to_transform().pre_transform(&rigid2.to_transform())));
}
}

244
third_party/rust/euclid/src/rotation.rs поставляемый
Просмотреть файл

@ -12,9 +12,13 @@ use num_traits::{Float, FloatConst, One, Zero, NumCast};
use core::fmt;
use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, Sub, SubAssign};
use core::marker::PhantomData;
use core::cmp::{Eq, PartialEq};
use core::hash::{Hash};
use trig::Trig;
use {TypedPoint2D, TypedPoint3D, TypedVector2D, TypedVector3D, Vector3D, point2, point3, vec3};
use {TypedTransform2D, TypedTransform3D, UnknownUnit};
use {Point2D, Point3D, Vector2D, Vector3D, point2, point3, vec3};
use {Transform2D, Transform3D, UnknownUnit};
#[cfg(feature = "serde")]
use serde;
/// An angle in radians
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Hash)]
@ -186,22 +190,49 @@ impl<T: Neg<Output = T>> Neg for Angle<T> {
}
/// A transform that can represent rotations in 2d, represented as an angle in radians.
#[derive(EuclidMatrix)]
#[repr(C)]
pub struct TypedRotation2D<T, Src, Dst> {
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(bound(serialize = "T: serde::Serialize", deserialize = "T: serde::Deserialize<'de>")))]
pub struct Rotation2D<T, Src, Dst> {
pub angle : T,
#[doc(hidden)]
pub _unit: PhantomData<(Src, Dst)>,
}
/// The default 2d rotation type with no units.
pub type Rotation2D<T> = TypedRotation2D<T, UnknownUnit, UnknownUnit>;
impl<T: Copy, Src, Dst> Copy for Rotation2D<T, Src, Dst> {}
impl<T, Src, Dst> TypedRotation2D<T, Src, Dst> {
impl<T: Clone, Src, Dst> Clone for Rotation2D<T, Src, Dst> {
fn clone(&self) -> Self {
Rotation2D {
angle: self.angle.clone(),
_unit: PhantomData,
}
}
}
impl<T, Src, Dst> Eq for Rotation2D<T, Src, Dst> where T: Eq {}
impl<T, Src, Dst> PartialEq for Rotation2D<T, Src, Dst>
where T: PartialEq
{
fn eq(&self, other: &Self) -> bool {
self.angle == other.angle
}
}
impl<T, Src, Dst> Hash for Rotation2D<T, Src, Dst>
where T: Hash
{
fn hash<H: ::core::hash::Hasher>(&self, h: &mut H) {
self.angle.hash(h);
}
}
impl<T, Src, Dst> Rotation2D<T, Src, Dst> {
#[inline]
/// Creates a rotation from an angle in radians.
pub fn new(angle: Angle<T>) -> Self {
TypedRotation2D {
Rotation2D {
angle: angle.radians,
_unit: PhantomData,
}
@ -221,7 +252,7 @@ impl<T, Src, Dst> TypedRotation2D<T, Src, Dst> {
}
}
impl<T, Src, Dst> TypedRotation2D<T, Src, Dst>
impl<T, Src, Dst> Rotation2D<T, Src, Dst>
where
T: Clone,
{
@ -231,7 +262,7 @@ where
}
}
impl<T, Src, Dst> TypedRotation2D<T, Src, Dst>
impl<T, Src, Dst> Rotation2D<T, Src, Dst>
where
T: Copy
+ Clone
@ -247,31 +278,31 @@ where
{
/// Creates a 3d rotation (around the z axis) from this 2d rotation.
#[inline]
pub fn to_3d(&self) -> TypedRotation3D<T, Src, Dst> {
TypedRotation3D::around_z(self.get_angle())
pub fn to_3d(&self) -> Rotation3D<T, Src, Dst> {
Rotation3D::around_z(self.get_angle())
}
/// Returns the inverse of this rotation.
#[inline]
pub fn inverse(&self) -> TypedRotation2D<T, Dst, Src> {
TypedRotation2D::radians(-self.angle)
pub fn inverse(&self) -> Rotation2D<T, Dst, Src> {
Rotation2D::radians(-self.angle)
}
/// Returns a rotation representing the other rotation followed by this rotation.
#[inline]
pub fn pre_rotate<NewSrc>(
&self,
other: &TypedRotation2D<T, NewSrc, Src>,
) -> TypedRotation2D<T, NewSrc, Dst> {
TypedRotation2D::radians(self.angle + other.angle)
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: &TypedRotation2D<T, Dst, NewDst>,
) -> TypedRotation2D<T, Src, NewDst> {
other: &Rotation2D<T, Dst, NewDst>,
) -> Rotation2D<T, Src, NewDst> {
other.pre_rotate(self)
}
@ -279,7 +310,7 @@ where
///
/// The input point must be use the unit Src, and the returned point has the unit Dst.
#[inline]
pub fn transform_point(&self, point: &TypedPoint2D<T, Src>) -> TypedPoint2D<T, Dst> {
pub fn transform_point(&self, point: Point2D<T, Src>) -> Point2D<T, Dst> {
let (sin, cos) = Float::sin_cos(self.angle);
point2(point.x * cos - point.y * sin, point.y * cos + point.x * sin)
}
@ -288,12 +319,12 @@ where
///
/// The input point must be use the unit Src, and the returned point has the unit Dst.
#[inline]
pub fn transform_vector(&self, vector: &TypedVector2D<T, Src>) -> TypedVector2D<T, Dst> {
self.transform_point(&vector.to_point()).to_vector()
pub fn transform_vector(&self, vector: Vector2D<T, Src>) -> Vector2D<T, Dst> {
self.transform_point(vector.to_point()).to_vector()
}
}
impl<T, Src, Dst> TypedRotation2D<T, Src, Dst>
impl<T, Src, Dst> Rotation2D<T, Src, Dst>
where
T: Copy
+ Clone
@ -308,8 +339,8 @@ where
{
/// Returns the matrix representation of this rotation.
#[inline]
pub fn to_transform(&self) -> TypedTransform2D<T, Src, Dst> {
TypedTransform2D::create_rotation(self.get_angle())
pub fn to_transform(&self) -> Transform2D<T, Src, Dst> {
Transform2D::create_rotation(self.get_angle())
}
}
@ -322,9 +353,10 @@ where
/// Some people use the `x, y, z, w` (or `w, x, y, z`) notations. The equivalence is
/// as follows: `x -> i`, `y -> j`, `z -> k`, `w -> r`.
/// The memory layout of this type corresponds to the `x, y, z, w` notation
#[derive(EuclidMatrix)]
#[repr(C)]
pub struct TypedRotation3D<T, Src, Dst> {
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(bound(serialize = "T: serde::Serialize", deserialize = "T: serde::Deserialize<'de>")))]
pub struct Rotation3D<T, Src, Dst> {
/// Component multiplied by the imaginary number `i`.
pub i: T,
/// Component multiplied by the imaginary number `j`.
@ -337,10 +369,45 @@ pub struct TypedRotation3D<T, Src, Dst> {
pub _unit: PhantomData<(Src, Dst)>,
}
/// The default 3d rotation type with no units.
pub type Rotation3D<T> = TypedRotation3D<T, UnknownUnit, UnknownUnit>;
impl<T: Copy, Src, Dst> Copy for Rotation3D<T, Src, Dst> {}
impl<T, Src, Dst> TypedRotation3D<T, Src, Dst> {
impl<T: Clone, Src, Dst> Clone for Rotation3D<T, Src, Dst> {
fn clone(&self) -> Self {
Rotation3D {
i: self.i.clone(),
j: self.j.clone(),
k: self.k.clone(),
r: self.r.clone(),
_unit: PhantomData,
}
}
}
impl<T, Src, Dst> Eq for Rotation3D<T, Src, Dst> where T: Eq {}
impl<T, Src, Dst> PartialEq for Rotation3D<T, Src, Dst>
where T: PartialEq
{
fn eq(&self, other: &Self) -> bool {
self.i == other.i &&
self.j == other.j &&
self.k == other.k &&
self.r == other.r
}
}
impl<T, Src, Dst> Hash for Rotation3D<T, Src, Dst>
where T: Hash
{
fn hash<H: ::core::hash::Hasher>(&self, h: &mut H) {
self.i.hash(h);
self.j.hash(h);
self.k.hash(h);
self.r.hash(h);
}
}
impl<T, Src, Dst> Rotation3D<T, Src, Dst> {
/// Creates a rotation around from a quaternion representation.
///
/// The parameters are a, b, c and r compose the quaternion `a*i + b*j + c*k + r`
@ -350,7 +417,7 @@ impl<T, Src, Dst> TypedRotation3D<T, Src, Dst> {
/// The resulting quaternion is not necessarily normalized. See `unit_quaternion`.
#[inline]
pub fn quaternion(a: T, b: T, c: T, r: T) -> Self {
TypedRotation3D {
Rotation3D {
i: a,
j: b,
k: c,
@ -360,18 +427,18 @@ impl<T, Src, Dst> TypedRotation3D<T, Src, Dst> {
}
}
impl<T, Src, Dst> TypedRotation3D<T, Src, Dst>
impl<T, Src, Dst> Rotation3D<T, Src, Dst>
where
T: Copy,
{
/// Returns the vector part (i, j, k) of this quaternion.
#[inline]
pub fn vector_part(&self) -> Vector3D<T> {
pub fn vector_part(&self) -> Vector3D<T, UnknownUnit> {
vec3(self.i, self.j, self.k)
}
}
impl<T, Src, Dst> TypedRotation3D<T, Src, Dst>
impl<T, Src, Dst> Rotation3D<T, Src, Dst>
where
T: Float,
{
@ -394,7 +461,7 @@ where
}
/// Creates a rotation around a given axis.
pub fn around_axis(axis: TypedVector3D<T, Src>, angle: Angle<T>) -> Self {
pub fn around_axis(axis: Vector3D<T, Src>, angle: Angle<T>) -> Self {
let axis = axis.normalize();
let two = T::one() + T::one();
let (sin, cos) = Angle::sin_cos(angle / two);
@ -449,8 +516,8 @@ where
/// Returns the inverse of this rotation.
#[inline]
pub fn inverse(&self) -> TypedRotation3D<T, Dst, Src> {
TypedRotation3D::quaternion(-self.i, -self.j, -self.k, self.r)
pub fn inverse(&self) -> Rotation3D<T, Dst, Src> {
Rotation3D::quaternion(-self.i, -self.j, -self.k, self.r)
}
/// Computes the norm of this quaternion
@ -533,7 +600,7 @@ where
/// Returns the given 3d point transformed by this rotation.
///
/// The input point must be use the unit Src, and the returned point has the unit Dst.
pub fn rotate_point3d(&self, point: &TypedPoint3D<T, Src>) -> TypedPoint3D<T, Dst>
pub fn transform_point3d(&self, point: Point3D<T, Src>) -> Point3D<T, Dst>
where
T: ApproxEq<T>,
{
@ -553,38 +620,38 @@ where
///
/// The input point must be use the unit Src, and the returned point has the unit Dst.
#[inline]
pub fn rotate_point2d(&self, point: &TypedPoint2D<T, Src>) -> TypedPoint2D<T, Dst>
pub fn transform_point2d(&self, point: Point2D<T, Src>) -> Point2D<T, Dst>
where
T: ApproxEq<T>,
{
self.rotate_point3d(&point.to_3d()).xy()
self.transform_point3d(point.to_3d()).xy()
}
/// Returns the given 3d vector transformed by this rotation.
///
/// The input vector must be use the unit Src, and the returned point has the unit Dst.
#[inline]
pub fn rotate_vector3d(&self, vector: &TypedVector3D<T, Src>) -> TypedVector3D<T, Dst>
pub fn transform_vector3d(&self, vector: Vector3D<T, Src>) -> Vector3D<T, Dst>
where
T: ApproxEq<T>,
{
self.rotate_point3d(&vector.to_point()).to_vector()
self.transform_point3d(vector.to_point()).to_vector()
}
/// Returns the given 2d vector transformed by this rotation then projected on the xy plane.
///
/// The input vector must be use the unit Src, and the returned point has the unit Dst.
#[inline]
pub fn rotate_vector2d(&self, vector: &TypedVector2D<T, Src>) -> TypedVector2D<T, Dst>
pub fn transform_vector2d(&self, vector: Vector2D<T, Src>) -> Vector2D<T, Dst>
where
T: ApproxEq<T>,
{
self.rotate_vector3d(&vector.to_3d()).xy()
self.transform_vector3d(vector.to_3d()).xy()
}
/// Returns the matrix representation of this rotation.
#[inline]
pub fn to_transform(&self) -> TypedTransform3D<T, Src, Dst>
pub fn to_transform(&self) -> Transform3D<T, Src, Dst>
where
T: ApproxEq<T>,
{
@ -618,7 +685,7 @@ where
let m32 = jk - ri;
let m33 = one - (ii + jj);
TypedTransform3D::row_major(
Transform3D::row_major(
m11,
m12,
m13,
@ -641,13 +708,13 @@ where
/// Returns a rotation representing the other rotation followed by this rotation.
pub fn pre_rotate<NewSrc>(
&self,
other: &TypedRotation3D<T, NewSrc, Src>,
) -> TypedRotation3D<T, NewSrc, Dst>
other: &Rotation3D<T, NewSrc, Src>,
) -> Rotation3D<T, NewSrc, Dst>
where
T: ApproxEq<T>,
{
debug_assert!(self.is_normalized());
TypedRotation3D::quaternion(
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,
@ -659,8 +726,8 @@ where
#[inline]
pub fn post_rotate<NewDst>(
&self,
other: &TypedRotation3D<T, Dst, NewDst>,
) -> TypedRotation3D<T, Src, NewDst>
other: &Rotation3D<T, Dst, NewDst>,
) -> Rotation3D<T, Src, NewDst>
where
T: ApproxEq<T>,
{
@ -701,7 +768,7 @@ where
}
}
impl<T: fmt::Debug, Src, Dst> fmt::Debug for TypedRotation3D<T, Src, Dst> {
impl<T: fmt::Debug, Src, Dst> fmt::Debug for Rotation3D<T, Src, Dst> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
@ -711,7 +778,7 @@ impl<T: fmt::Debug, Src, Dst> fmt::Debug for TypedRotation3D<T, Src, Dst> {
}
}
impl<T: fmt::Display, Src, Dst> fmt::Display for TypedRotation3D<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,
@ -721,7 +788,7 @@ impl<T: fmt::Display, Src, Dst> fmt::Display for TypedRotation3D<T, Src, Dst> {
}
}
impl<T, Src, Dst> ApproxEq<T> for TypedRotation3D<T, Src, Dst>
impl<T, Src, Dst> ApproxEq<T> for Rotation3D<T, Src, Dst>
where
T: Copy + Neg<Output = T> + ApproxEq<T>,
{
@ -745,72 +812,78 @@ where
#[test]
fn simple_rotation_2d() {
use core::f32::consts::{FRAC_PI_2, PI};
use default::Rotation2D;
let ri = Rotation2D::identity();
let r90 = Rotation2D::radians(FRAC_PI_2);
let rm90 = Rotation2D::radians(-FRAC_PI_2);
let r180 = Rotation2D::radians(PI);
assert!(
ri.transform_point(&point2(1.0, 2.0))
ri.transform_point(point2(1.0, 2.0))
.approx_eq(&point2(1.0, 2.0))
);
assert!(
r90.transform_point(&point2(1.0, 2.0))
r90.transform_point(point2(1.0, 2.0))
.approx_eq(&point2(-2.0, 1.0))
);
assert!(
rm90.transform_point(&point2(1.0, 2.0))
rm90.transform_point(point2(1.0, 2.0))
.approx_eq(&point2(2.0, -1.0))
);
assert!(
r180.transform_point(&point2(1.0, 2.0))
r180.transform_point(point2(1.0, 2.0))
.approx_eq(&point2(-1.0, -2.0))
);
assert!(
r90.inverse()
.inverse()
.transform_point(&point2(1.0, 2.0))
.approx_eq(&r90.transform_point(&point2(1.0, 2.0)))
.transform_point(point2(1.0, 2.0))
.approx_eq(&r90.transform_point(point2(1.0, 2.0)))
);
}
#[test]
fn simple_rotation_3d_in_2d() {
use core::f32::consts::{FRAC_PI_2, PI};
use default::Rotation3D;
let ri = Rotation3D::identity();
let r90 = Rotation3D::around_z(Angle::radians(FRAC_PI_2));
let rm90 = Rotation3D::around_z(Angle::radians(-FRAC_PI_2));
let r180 = Rotation3D::around_z(Angle::radians(PI));
assert!(
ri.rotate_point2d(&point2(1.0, 2.0))
ri.transform_point2d(point2(1.0, 2.0))
.approx_eq(&point2(1.0, 2.0))
);
assert!(
r90.rotate_point2d(&point2(1.0, 2.0))
r90.transform_point2d(point2(1.0, 2.0))
.approx_eq(&point2(-2.0, 1.0))
);
assert!(
rm90.rotate_point2d(&point2(1.0, 2.0))
rm90.transform_point2d(point2(1.0, 2.0))
.approx_eq(&point2(2.0, -1.0))
);
assert!(
r180.rotate_point2d(&point2(1.0, 2.0))
r180.transform_point2d(point2(1.0, 2.0))
.approx_eq(&point2(-1.0, -2.0))
);
assert!(
r90.inverse()
.inverse()
.rotate_point2d(&point2(1.0, 2.0))
.approx_eq(&r90.rotate_point2d(&point2(1.0, 2.0)))
.transform_point2d(point2(1.0, 2.0))
.approx_eq(&r90.transform_point2d(point2(1.0, 2.0)))
);
}
#[test]
fn pre_post() {
use core::f32::consts::FRAC_PI_2;
use default::Rotation3D;
let r1 = Rotation3D::around_x(Angle::radians(FRAC_PI_2));
let r2 = Rotation3D::around_y(Angle::radians(FRAC_PI_2));
let r3 = Rotation3D::around_z(Angle::radians(FRAC_PI_2));
@ -823,18 +896,20 @@ fn pre_post() {
// Check that the order of transformations is correct (corresponds to what
// we do in Transform3D).
let p1 = r1.post_rotate(&r2).post_rotate(&r3).rotate_point3d(&p);
let p2 = t1.post_mul(&t2).post_mul(&t3).transform_point3d(&p);
let p1 = r1.post_rotate(&r2).post_rotate(&r3).transform_point3d(p);
let p2 = t1.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.post_mul(&t1).post_mul(&t2).transform_point3d(&p);
let p3 = t3.post_transform(&t1).post_transform(&t2).transform_point3d(p);
assert!(!p1.approx_eq(&p3.unwrap()));
}
#[test]
fn to_transform3d() {
use default::Rotation3D;
use core::f32::consts::{FRAC_PI_2, PI};
let rotations = [
Rotation3D::identity(),
@ -857,8 +932,8 @@ fn to_transform3d() {
];
for rotation in &rotations {
for point in &points {
let p1 = rotation.rotate_point3d(point);
for &point in &points {
let p1 = rotation.transform_point3d(point);
let p2 = rotation.to_transform().transform_point3d(point);
assert!(p1.approx_eq(&p2.unwrap()));
}
@ -867,6 +942,8 @@ fn to_transform3d() {
#[test]
fn slerp() {
use default::Rotation3D;
let q1 = Rotation3D::quaternion(1.0, 0.0, 0.0, 0.0);
let q2 = Rotation3D::quaternion(0.0, 1.0, 0.0, 0.0);
let q3 = Rotation3D::quaternion(0.0, 0.0, -1.0, 0.0);
@ -936,22 +1013,23 @@ fn slerp() {
#[test]
fn around_axis() {
use core::f32::consts::{FRAC_PI_2, PI};
use default::Rotation3D;
// Two sort of trivial cases:
let r1 = Rotation3D::around_axis(vec3(1.0, 1.0, 0.0), Angle::radians(PI));
let r2 = Rotation3D::around_axis(vec3(1.0, 1.0, 0.0), Angle::radians(FRAC_PI_2));
assert!(
r1.rotate_point3d(&point3(1.0, 2.0, 0.0))
r1.transform_point3d(point3(1.0, 2.0, 0.0))
.approx_eq(&point3(2.0, 1.0, 0.0))
);
assert!(
r2.rotate_point3d(&point3(1.0, 0.0, 0.0))
r2.transform_point3d(point3(1.0, 0.0, 0.0))
.approx_eq(&point3(0.5, 0.5, -0.5.sqrt()))
);
// A more arbitrary test (made up with numpy):
let r3 = Rotation3D::around_axis(vec3(0.5, 1.0, 2.0), Angle::radians(2.291288));
assert!(r3.rotate_point3d(&point3(1.0, 0.0, 0.0)).approx_eq(&point3(
assert!(r3.transform_point3d(point3(1.0, 0.0, 0.0)).approx_eq(&point3(
-0.58071821,
0.81401868,
-0.01182979
@ -961,6 +1039,7 @@ fn around_axis() {
#[test]
fn from_euler() {
use core::f32::consts::FRAC_PI_2;
use default::Rotation3D;
// First test simple separate yaw pitch and roll rotations, because it is easy to come
// up with the corresponding quaternion.
@ -974,20 +1053,20 @@ fn from_euler() {
// roll
let roll_re = Rotation3D::euler(angle, zero, zero);
let roll_rq = Rotation3D::around_x(angle);
let roll_pe = roll_re.rotate_point3d(&p);
let roll_pq = roll_rq.rotate_point3d(&p);
let roll_pe = roll_re.transform_point3d(p);
let roll_pq = roll_rq.transform_point3d(p);
// pitch
let pitch_re = Rotation3D::euler(zero, angle, zero);
let pitch_rq = Rotation3D::around_y(angle);
let pitch_pe = pitch_re.rotate_point3d(&p);
let pitch_pq = pitch_rq.rotate_point3d(&p);
let pitch_pe = pitch_re.transform_point3d(p);
let pitch_pq = pitch_rq.transform_point3d(p);
// yaw
let yaw_re = Rotation3D::euler(zero, zero, angle);
let yaw_rq = Rotation3D::around_z(angle);
let yaw_pe = yaw_re.rotate_point3d(&p);
let yaw_pq = yaw_rq.rotate_point3d(&p);
let yaw_pe = yaw_re.transform_point3d(p);
let yaw_pq = yaw_rq.transform_point3d(p);
assert!(roll_pe.approx_eq(&roll_pq));
assert!(pitch_pe.approx_eq(&pitch_pq));
@ -997,8 +1076,8 @@ fn from_euler() {
// the proper order: roll -> pitch -> yaw.
let ypr_e = Rotation3D::euler(angle, angle, angle);
let ypr_q = roll_rq.post_rotate(&pitch_rq).post_rotate(&yaw_rq);
let ypr_pe = ypr_e.rotate_point3d(&p);
let ypr_pq = ypr_q.rotate_point3d(&p);
let ypr_pe = ypr_e.transform_point3d(p);
let ypr_pq = ypr_q.transform_point3d(p);
assert!(ypr_pe.approx_eq(&ypr_pq));
}
@ -1006,6 +1085,7 @@ fn from_euler() {
#[test]
fn wrap_angles() {
use core::f32::consts::{FRAC_PI_2, PI};
assert!(Angle::radians(0.0).positive().radians.approx_eq(&0.0));
assert!(
Angle::radians(FRAC_PI_2)

155
third_party/rust/euclid/src/scale.rs поставляемый
Просмотреть файл

@ -12,162 +12,135 @@ use num::One;
use num_traits::NumCast;
#[cfg(feature = "serde")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde;
use core::fmt;
use core::ops::{Add, Div, Mul, Neg, Sub};
use core::marker::PhantomData;
use {TypedPoint2D, TypedRect, TypedSize2D, TypedVector2D};
use {Point2D, Rect, Size2D, Vector2D};
/// A scaling factor between two different units of measurement.
///
/// This is effectively a type-safe float, intended to be used in combination with other types like
/// `length::Length` to enforce conversion between systems of measurement at compile time.
///
/// `Src` and `Dst` represent the units before and after multiplying a value by a `TypedScale`. They
/// `Src` and `Dst` represent the units before and after multiplying a value by a `Scale`. They
/// may be types without values, such as empty enums. For example:
///
/// ```rust
/// use euclid::TypedScale;
/// use euclid::Scale;
/// use euclid::Length;
/// enum Mm {};
/// enum Inch {};
///
/// let mm_per_inch: TypedScale<f32, Inch, Mm> = TypedScale::new(25.4);
/// let mm_per_inch: Scale<f32, Inch, Mm> = Scale::new(25.4);
///
/// let one_foot: Length<f32, Inch> = Length::new(12.0);
/// let one_foot_in_mm: Length<f32, Mm> = one_foot * mm_per_inch;
/// ```
#[repr(C)]
pub struct TypedScale<T, Src, Dst>(pub T, #[doc(hidden)] pub PhantomData<(Src, Dst)>);
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(bound(serialize = "T: serde::Serialize", deserialize = "T: serde::Deserialize<'de>")))]
pub struct Scale<T, Src, Dst>(pub T, #[doc(hidden)] pub PhantomData<(Src, Dst)>);
#[cfg(feature = "serde")]
impl<'de, T, Src, Dst> Deserialize<'de> for TypedScale<T, Src, Dst>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<TypedScale<T, Src, Dst>, D::Error>
where
D: Deserializer<'de>,
{
Ok(TypedScale(
try!(Deserialize::deserialize(deserializer)),
PhantomData,
))
}
}
#[cfg(feature = "serde")]
impl<T, Src, Dst> Serialize for TypedScale<T, Src, Dst>
where
T: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.0.serialize(serializer)
}
}
impl<T, Src, Dst> TypedScale<T, Src, Dst> {
impl<T, Src, Dst> Scale<T, Src, Dst> {
pub fn new(x: T) -> Self {
TypedScale(x, PhantomData)
Scale(x, PhantomData)
}
}
impl<T: Clone, Src, Dst> TypedScale<T, Src, Dst> {
impl<T: Clone, Src, Dst> Scale<T, Src, Dst> {
pub fn get(&self) -> T {
self.0.clone()
}
}
impl<Src, Dst> TypedScale<f32, Src, Dst> {
impl<Src, Dst> Scale<f32, Src, Dst> {
/// Identity scaling, could be used to safely transit from one space to another.
pub const ONE: Self = TypedScale(1.0, PhantomData);
pub const ONE: Self = Scale(1.0, PhantomData);
}
impl<T: Clone + One + Div<T, Output = T>, Src, Dst> TypedScale<T, Src, Dst> {
/// The inverse TypedScale (1.0 / self).
pub fn inv(&self) -> TypedScale<T, Dst, Src> {
impl<T: Clone + One + Div<T, Output = T>, Src, Dst> Scale<T, Src, Dst> {
/// The inverse Scale (1.0 / self).
pub fn inv(&self) -> Scale<T, Dst, Src> {
let one: T = One::one();
TypedScale::new(one / self.get())
Scale::new(one / self.get())
}
}
// scale0 * scale1
impl<T: Clone + Mul<T, Output = T>, A, B, C> Mul<TypedScale<T, B, C>> for TypedScale<T, A, B> {
type Output = TypedScale<T, A, C>;
impl<T: Clone + Mul<T, Output = T>, A, B, C> Mul<Scale<T, B, C>> for Scale<T, A, B> {
type Output = Scale<T, A, C>;
#[inline]
fn mul(self, other: TypedScale<T, B, C>) -> TypedScale<T, A, C> {
TypedScale::new(self.get() * other.get())
fn mul(self, other: Scale<T, B, C>) -> Scale<T, A, C> {
Scale::new(self.get() * other.get())
}
}
// scale0 + scale1
impl<T: Clone + Add<T, Output = T>, Src, Dst> Add for TypedScale<T, Src, Dst> {
type Output = TypedScale<T, Src, Dst>;
impl<T: Clone + Add<T, Output = T>, Src, Dst> Add for Scale<T, Src, Dst> {
type Output = Scale<T, Src, Dst>;
#[inline]
fn add(self, other: TypedScale<T, Src, Dst>) -> TypedScale<T, Src, Dst> {
TypedScale::new(self.get() + other.get())
fn add(self, other: Scale<T, Src, Dst>) -> Scale<T, Src, Dst> {
Scale::new(self.get() + other.get())
}
}
// scale0 - scale1
impl<T: Clone + Sub<T, Output = T>, Src, Dst> Sub for TypedScale<T, Src, Dst> {
type Output = TypedScale<T, Src, Dst>;
impl<T: Clone + Sub<T, Output = T>, Src, Dst> Sub for Scale<T, Src, Dst> {
type Output = Scale<T, Src, Dst>;
#[inline]
fn sub(self, other: TypedScale<T, Src, Dst>) -> TypedScale<T, Src, Dst> {
TypedScale::new(self.get() - other.get())
fn sub(self, other: Scale<T, Src, Dst>) -> Scale<T, Src, Dst> {
Scale::new(self.get() - other.get())
}
}
impl<T: NumCast + Clone, Src, Dst0> TypedScale<T, Src, Dst0> {
impl<T: NumCast + Clone, Src, Dst0> Scale<T, Src, Dst0> {
/// Cast from one numeric representation to another, preserving the units.
pub fn cast<T1: NumCast + Clone>(&self) -> TypedScale<T1, Src, Dst0> {
pub fn cast<T1: NumCast + Clone>(&self) -> Scale<T1, Src, Dst0> {
self.try_cast().unwrap()
}
/// Fallible cast from one numeric representation to another, preserving the units.
pub fn try_cast<T1: NumCast + Clone>(&self) -> Option<TypedScale<T1, Src, Dst0>> {
NumCast::from(self.get()).map(TypedScale::new)
pub fn try_cast<T1: NumCast + Clone>(&self) -> Option<Scale<T1, Src, Dst0>> {
NumCast::from(self.get()).map(Scale::new)
}
}
impl<T, Src, Dst> TypedScale<T, Src, Dst>
impl<T, Src, Dst> Scale<T, Src, Dst>
where
T: Copy + Clone + Mul<T, Output = T> + Neg<Output = T> + PartialEq + One,
{
/// Returns the given point transformed by this scale.
#[inline]
pub fn transform_point(&self, point: &TypedPoint2D<T, Src>) -> TypedPoint2D<T, Dst> {
TypedPoint2D::new(point.x * self.get(), point.y * self.get())
pub fn transform_point(&self, point: Point2D<T, Src>) -> Point2D<T, Dst> {
Point2D::new(point.x * self.get(), point.y * self.get())
}
/// Returns the given vector transformed by this scale.
#[inline]
pub fn transform_vector(&self, vec: &TypedVector2D<T, Src>) -> TypedVector2D<T, Dst> {
TypedVector2D::new(vec.x * self.get(), vec.y * self.get())
pub fn transform_vector(&self, vec: Vector2D<T, Src>) -> Vector2D<T, Dst> {
Vector2D::new(vec.x * self.get(), vec.y * self.get())
}
/// Returns the given vector transformed by this scale.
#[inline]
pub fn transform_size(&self, size: &TypedSize2D<T, Src>) -> TypedSize2D<T, Dst> {
TypedSize2D::new(size.width * self.get(), size.height * self.get())
pub fn transform_size(&self, size: Size2D<T, Src>) -> Size2D<T, Dst> {
Size2D::new(size.width * self.get(), size.height * self.get())
}
/// Returns the given rect transformed by this scale.
#[inline]
pub fn transform_rect(&self, rect: &TypedRect<T, Src>) -> TypedRect<T, Dst> {
TypedRect::new(
self.transform_point(&rect.origin),
self.transform_size(&rect.size),
pub fn transform_rect(&self, rect: &Rect<T, Src>) -> Rect<T, Dst> {
Rect::new(
self.transform_point(rect.origin),
self.transform_size(rect.size),
)
}
/// Returns the inverse of this scale.
#[inline]
pub fn inverse(&self) -> TypedScale<T, Dst, Src> {
TypedScale::new(-self.get())
pub fn inverse(&self) -> Scale<T, Dst, Src> {
Scale::new(-self.get())
}
/// Returns true if this scale has no effect.
@ -180,27 +153,27 @@ where
// FIXME: Switch to `derive(PartialEq, Clone)` after this Rust issue is fixed:
// https://github.com/mozilla/rust/issues/7671
impl<T: PartialEq, Src, Dst> PartialEq for TypedScale<T, Src, Dst> {
fn eq(&self, other: &TypedScale<T, Src, Dst>) -> bool {
impl<T: PartialEq, Src, Dst> PartialEq for Scale<T, Src, Dst> {
fn eq(&self, other: &Scale<T, Src, Dst>) -> bool {
self.0 == other.0
}
}
impl<T: Clone, Src, Dst> Clone for TypedScale<T, Src, Dst> {
fn clone(&self) -> TypedScale<T, Src, Dst> {
TypedScale::new(self.get())
impl<T: Clone, Src, Dst> Clone for Scale<T, Src, Dst> {
fn clone(&self) -> Scale<T, Src, Dst> {
Scale::new(self.get())
}
}
impl<T: Copy, Src, Dst> Copy for TypedScale<T, Src, Dst> {}
impl<T: Copy, Src, Dst> Copy for Scale<T, Src, Dst> {}
impl<T: fmt::Debug, Src, Dst> fmt::Debug for TypedScale<T, Src, Dst> {
impl<T: fmt::Debug, Src, Dst> fmt::Debug for Scale<T, Src, Dst> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}
impl<T: fmt::Display, Src, Dst> fmt::Display for TypedScale<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)
}
@ -208,7 +181,7 @@ impl<T: fmt::Display, Src, Dst> fmt::Display for TypedScale<T, Src, Dst> {
#[cfg(test)]
mod tests {
use super::TypedScale;
use super::Scale;
enum Inch {}
enum Cm {}
@ -216,20 +189,20 @@ mod tests {
#[test]
fn test_scale() {
let mm_per_inch: TypedScale<f32, Inch, Mm> = TypedScale::new(25.4);
let cm_per_mm: TypedScale<f32, Mm, Cm> = TypedScale::new(0.1);
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: TypedScale<f32, Cm, Mm> = cm_per_mm.inv();
let mm_per_cm: Scale<f32, Cm, Mm> = cm_per_mm.inv();
assert_eq!(mm_per_cm.get(), 10.0);
let cm_per_inch: TypedScale<f32, Inch, Cm> = mm_per_inch * cm_per_mm;
assert_eq!(cm_per_inch, TypedScale::new(2.54));
let cm_per_inch: Scale<f32, Inch, Cm> = mm_per_inch * cm_per_mm;
assert_eq!(cm_per_inch, Scale::new(2.54));
let a: TypedScale<isize, Inch, Inch> = TypedScale::new(2);
let b: TypedScale<isize, Inch, Inch> = TypedScale::new(3);
let a: Scale<isize, Inch, Inch> = Scale::new(2);
let b: Scale<isize, Inch, Inch> = Scale::new(3);
assert!(a != b);
assert_eq!(a, a.clone());
assert_eq!(a.clone() + b.clone(), TypedScale::new(5));
assert_eq!(a - b, TypedScale::new(-1));
assert_eq!(a.clone() + b.clone(), Scale::new(5));
assert_eq!(a - b, Scale::new(-1));
}
}

105
third_party/rust/euclid/src/side_offsets.rs поставляемый
Просмотреть файл

@ -10,18 +10,22 @@
//! A group of side offsets, which correspond to top/left/bottom/right for borders, padding,
//! and margins in CSS.
use super::UnknownUnit;
use length::Length;
use num::Zero;
use core::fmt;
use core::ops::Add;
use core::marker::PhantomData;
use core::cmp::{Eq, PartialEq};
use core::hash::{Hash};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
/// A group of 2D side offsets, which correspond to top/left/bottom/right for borders, padding,
/// and margins in CSS, optionally tagged with a unit.
#[derive(EuclidMatrix)]
#[repr(C)]
pub struct TypedSideOffsets2D<T, U> {
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(bound(serialize = "T: Serialize", deserialize = "T: Deserialize<'de>")))]
pub struct SideOffsets2D<T, U> {
pub top: T,
pub right: T,
pub bottom: T,
@ -30,7 +34,45 @@ pub struct TypedSideOffsets2D<T, U> {
pub _unit: PhantomData<U>,
}
impl<T: fmt::Debug, U> fmt::Debug for TypedSideOffsets2D<T, U> {
impl<T: Copy, U> Copy for SideOffsets2D<T, U> {}
impl<T: Clone, U> Clone for SideOffsets2D<T, U> {
fn clone(&self) -> Self {
SideOffsets2D {
top: self.top.clone(),
right: self.right.clone(),
bottom: self.bottom.clone(),
left: self.left.clone(),
_unit: PhantomData,
}
}
}
impl<T, U> Eq for SideOffsets2D<T, U> where T: Eq {}
impl<T, U> PartialEq for SideOffsets2D<T, U>
where T: PartialEq
{
fn eq(&self, other: &Self) -> bool {
self.top == other.top &&
self.right == other.right &&
self.bottom == other.bottom &&
self.left == other.left
}
}
impl<T, U> Hash for SideOffsets2D<T, U>
where T: Hash
{
fn hash<H: ::core::hash::Hasher>(&self, h: &mut H) {
self.top.hash(h);
self.right.hash(h);
self.bottom.hash(h);
self.left.hash(h);
}
}
impl<T: fmt::Debug, U> fmt::Debug for SideOffsets2D<T, U> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
@ -40,9 +82,9 @@ impl<T: fmt::Debug, U> fmt::Debug for TypedSideOffsets2D<T, U> {
}
}
impl<T: Default, U> Default for TypedSideOffsets2D<T, U> {
impl<T: Default, U> Default for SideOffsets2D<T, U> {
fn default() -> Self {
TypedSideOffsets2D {
SideOffsets2D {
top: Default::default(),
right: Default::default(),
bottom: Default::default(),
@ -52,13 +94,10 @@ impl<T: Default, U> Default for TypedSideOffsets2D<T, U> {
}
}
/// The default 2D side offset type with no unit.
pub type SideOffsets2D<T> = TypedSideOffsets2D<T, UnknownUnit>;
impl<T: Copy, U> TypedSideOffsets2D<T, U> {
impl<T: Copy, U> SideOffsets2D<T, U> {
/// Constructor taking a scalar for each side.
pub fn new(top: T, right: T, bottom: T, left: T) -> Self {
TypedSideOffsets2D {
SideOffsets2D {
top,
right,
bottom,
@ -74,41 +113,21 @@ impl<T: Copy, U> TypedSideOffsets2D<T, U> {
bottom: Length<T, U>,
left: Length<T, U>,
) -> Self {
TypedSideOffsets2D::new(top.0, right.0, bottom.0, left.0)
}
/// Access self.top as a typed Length instead of a scalar value.
pub fn top_typed(&self) -> Length<T, U> {
Length::new(self.top)
}
/// Access self.right as a typed Length instead of a scalar value.
pub fn right_typed(&self) -> Length<T, U> {
Length::new(self.right)
}
/// Access self.bottom as a typed Length instead of a scalar value.
pub fn bottom_typed(&self) -> Length<T, U> {
Length::new(self.bottom)
}
/// Access self.left as a typed Length instead of a scalar value.
pub fn left_typed(&self) -> Length<T, U> {
Length::new(self.left)
SideOffsets2D::new(top.0, right.0, bottom.0, left.0)
}
/// Constructor setting the same value to all sides, taking a scalar value directly.
pub fn new_all_same(all: T) -> Self {
TypedSideOffsets2D::new(all, all, all, all)
SideOffsets2D::new(all, all, all, all)
}
/// Constructor setting the same value to all sides, taking a typed Length.
pub fn from_length_all_same(all: Length<T, U>) -> Self {
TypedSideOffsets2D::new_all_same(all.0)
SideOffsets2D::new_all_same(all.0)
}
}
impl<T, U> TypedSideOffsets2D<T, U>
impl<T, U> SideOffsets2D<T, U>
where
T: Add<T, Output = T> + Copy,
{
@ -119,23 +138,15 @@ where
pub fn vertical(&self) -> T {
self.top + self.bottom
}
pub fn horizontal_typed(&self) -> Length<T, U> {
Length::new(self.horizontal())
}
pub fn vertical_typed(&self) -> Length<T, U> {
Length::new(self.vertical())
}
}
impl<T, U> Add for TypedSideOffsets2D<T, U>
impl<T, U> Add for SideOffsets2D<T, U>
where
T: Copy + Add<T, Output = T>,
{
type Output = Self;
fn add(self, other: Self) -> Self {
TypedSideOffsets2D::new(
SideOffsets2D::new(
self.top + other.top,
self.right + other.right,
self.bottom + other.bottom,
@ -144,9 +155,9 @@ where
}
}
impl<T: Copy + Zero, U> TypedSideOffsets2D<T, U> {
impl<T: Copy + Zero, U> SideOffsets2D<T, U> {
/// Constructor, setting all sides to zero.
pub fn zero() -> Self {
TypedSideOffsets2D::new(Zero::zero(), Zero::zero(), Zero::zero(), Zero::zero())
SideOffsets2D::new(Zero::zero(), Zero::zero(), Zero::zero(), Zero::zero())
}
}

448
third_party/rust/euclid/src/size.rs поставляемый
Просмотреть файл

@ -11,53 +11,105 @@ use super::UnknownUnit;
#[cfg(feature = "mint")]
use mint;
use length::Length;
use scale::TypedScale;
use vector::{TypedVector2D, vec2, BoolVector2D};
use vector::{TypedVector3D, vec3, BoolVector3D};
use scale::Scale;
use vector::{Vector2D, vec2, BoolVector2D};
use vector::{Vector3D, vec3, BoolVector3D};
use num::*;
use num_traits::{Float, NumCast, Signed};
use core::fmt;
use core::ops::{Add, Div, Mul, Sub};
use core::marker::PhantomData;
use core::cmp::{Eq, PartialEq};
use core::hash::{Hash};
#[cfg(feature = "serde")]
use serde;
/// A 2d size tagged with a unit.
#[derive(EuclidMatrix)]
#[repr(C)]
pub struct TypedSize2D<T, U> {
pub struct Size2D<T, U> {
pub width: T,
pub height: T,
#[doc(hidden)]
pub _unit: PhantomData<U>,
}
/// Default 2d size type with no unit.
///
/// `Size2D` provides the same methods as `TypedSize2D`.
pub type Size2D<T> = TypedSize2D<T, UnknownUnit>;
impl<T: Copy, U> Copy for Size2D<T, U> {}
impl<T: fmt::Debug, U> fmt::Debug for TypedSize2D<T, U> {
impl<T: Clone, U> Clone for Size2D<T, U> {
fn clone(&self) -> Self {
Size2D {
width: self.width.clone(),
height: self.height.clone(),
_unit: PhantomData,
}
}
}
#[cfg(feature = "serde")]
impl<'de, T, U> serde::Deserialize<'de> for Size2D<T, U>
where T: serde::Deserialize<'de>
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: serde::Deserializer<'de>
{
let (width, height) = try!(serde::Deserialize::deserialize(deserializer));
Ok(Size2D { width, height, _unit: PhantomData })
}
}
#[cfg(feature = "serde")]
impl<T, U> serde::Serialize for Size2D<T, U>
where T: serde::Serialize
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: serde::Serializer
{
(&self.width, &self.height).serialize(serializer)
}
}
impl<T, U> Eq for Size2D<T, U> where T: Eq {}
impl<T, U> PartialEq for Size2D<T, U>
where T: PartialEq
{
fn eq(&self, other: &Self) -> bool {
self.width == other.width && self.height == other.height
}
}
impl<T, U> Hash for Size2D<T, U>
where T: Hash
{
fn hash<H: ::core::hash::Hasher>(&self, h: &mut H) {
self.width.hash(h);
self.height.hash(h);
}
}
impl<T: fmt::Debug, U> fmt::Debug for Size2D<T, U> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}×{:?}", self.width, self.height)
}
}
impl<T: fmt::Display, U> fmt::Display for TypedSize2D<T, U> {
impl<T: fmt::Display, U> fmt::Display for Size2D<T, U> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "({}x{})", self.width, self.height)
}
}
impl<T: Default, U> Default for TypedSize2D<T, U> {
impl<T: Default, U> Default for Size2D<T, U> {
fn default() -> Self {
TypedSize2D::new(Default::default(), Default::default())
Size2D::new(Default::default(), Default::default())
}
}
impl<T, U> TypedSize2D<T, U> {
impl<T, U> Size2D<T, U> {
/// Constructor taking scalar values.
pub fn new(width: T, height: T) -> Self {
TypedSize2D {
Size2D {
width,
height,
_unit: PhantomData,
@ -65,61 +117,61 @@ impl<T, U> TypedSize2D<T, U> {
}
}
impl<T: Clone, U> TypedSize2D<T, U> {
impl<T: Clone, U> Size2D<T, U> {
/// Constructor taking scalar strongly typed lengths.
pub fn from_lengths(width: Length<T, U>, height: Length<T, U>) -> Self {
TypedSize2D::new(width.get(), height.get())
Size2D::new(width.get(), height.get())
}
}
impl<T: Round, U> TypedSize2D<T, U> {
impl<T: Round, U> Size2D<T, U> {
/// Rounds each component to the nearest integer value.
///
/// This behavior is preserved for negative values (unlike the basic cast).
pub fn round(&self) -> Self {
TypedSize2D::new(self.width.round(), self.height.round())
Size2D::new(self.width.round(), self.height.round())
}
}
impl<T: Ceil, U> TypedSize2D<T, U> {
impl<T: Ceil, U> Size2D<T, U> {
/// Rounds each component to the smallest integer equal or greater than the original value.
///
/// This behavior is preserved for negative values (unlike the basic cast).
pub fn ceil(&self) -> Self {
TypedSize2D::new(self.width.ceil(), self.height.ceil())
Size2D::new(self.width.ceil(), self.height.ceil())
}
}
impl<T: Floor, U> TypedSize2D<T, U> {
impl<T: Floor, U> Size2D<T, U> {
/// Rounds each component to the biggest integer equal or lower than the original value.
///
/// This behavior is preserved for negative values (unlike the basic cast).
pub fn floor(&self) -> Self {
TypedSize2D::new(self.width.floor(), self.height.floor())
Size2D::new(self.width.floor(), self.height.floor())
}
}
impl<T: Copy + Add<T, Output = T>, U> Add for TypedSize2D<T, U> {
impl<T: Copy + Add<T, Output = T>, U> Add for Size2D<T, U> {
type Output = Self;
fn add(self, other: Self) -> Self {
TypedSize2D::new(self.width + other.width, self.height + other.height)
Size2D::new(self.width + other.width, self.height + other.height)
}
}
impl<T: Copy + Sub<T, Output = T>, U> Sub for TypedSize2D<T, U> {
impl<T: Copy + Sub<T, Output = T>, U> Sub for Size2D<T, U> {
type Output = Self;
fn sub(self, other: Self) -> Self {
TypedSize2D::new(self.width - other.width, self.height - other.height)
Size2D::new(self.width - other.width, self.height - other.height)
}
}
impl<T: Copy + Clone + Mul<T>, U> TypedSize2D<T, U> {
impl<T: Copy + Clone + Mul<T>, U> Size2D<T, U> {
pub fn area(&self) -> T::Output {
self.width * self.height
}
}
impl<T, U> TypedSize2D<T, U>
impl<T, U> Size2D<T, U>
where
T: Copy + One + Add<Output = T> + Sub<Output = T> + Mul<Output = T>,
{
@ -136,70 +188,59 @@ where
}
}
impl<T: Zero + PartialOrd, U> TypedSize2D<T, U> {
impl<T: Zero + PartialOrd, U> Size2D<T, U> {
pub fn is_empty_or_negative(&self) -> bool {
let zero = T::zero();
self.width <= zero || self.height <= zero
}
}
impl<T: Zero, U> TypedSize2D<T, U> {
impl<T: Zero, U> Size2D<T, U> {
pub fn zero() -> Self {
TypedSize2D::new(Zero::zero(), Zero::zero())
Size2D::new(Zero::zero(), Zero::zero())
}
}
impl<T: Zero, U> Zero for TypedSize2D<T, U> {
impl<T: Zero, U> Zero for Size2D<T, U> {
fn zero() -> Self {
TypedSize2D::new(Zero::zero(), Zero::zero())
Size2D::new(Zero::zero(), Zero::zero())
}
}
impl<T: Copy + Mul<T, Output = T>, U> Mul<T> for TypedSize2D<T, U> {
impl<T: Copy + Mul<T, Output = T>, U> Mul<T> for Size2D<T, U> {
type Output = Self;
#[inline]
fn mul(self, scale: T) -> Self {
TypedSize2D::new(self.width * scale, self.height * scale)
Size2D::new(self.width * scale, self.height * scale)
}
}
impl<T: Copy + Div<T, Output = T>, U> Div<T> for TypedSize2D<T, U> {
impl<T: Copy + Div<T, Output = T>, U> Div<T> for Size2D<T, U> {
type Output = Self;
#[inline]
fn div(self, scale: T) -> Self {
TypedSize2D::new(self.width / scale, self.height / scale)
Size2D::new(self.width / scale, self.height / scale)
}
}
impl<T: Copy + Mul<T, Output = T>, U1, U2> Mul<TypedScale<T, U1, U2>> for TypedSize2D<T, U1> {
type Output = TypedSize2D<T, U2>;
impl<T: Copy + Mul<T, Output = T>, U1, U2> Mul<Scale<T, U1, U2>> for Size2D<T, U1> {
type Output = Size2D<T, U2>;
#[inline]
fn mul(self, scale: TypedScale<T, U1, U2>) -> TypedSize2D<T, U2> {
TypedSize2D::new(self.width * scale.get(), self.height * scale.get())
fn mul(self, scale: Scale<T, U1, U2>) -> Size2D<T, U2> {
Size2D::new(self.width * scale.get(), self.height * scale.get())
}
}
impl<T: Copy + Div<T, Output = T>, U1, U2> Div<TypedScale<T, U1, U2>> for TypedSize2D<T, U2> {
type Output = TypedSize2D<T, U1>;
impl<T: Copy + Div<T, Output = T>, U1, U2> Div<Scale<T, U1, U2>> for Size2D<T, U2> {
type Output = Size2D<T, U1>;
#[inline]
fn div(self, scale: TypedScale<T, U1, U2>) -> TypedSize2D<T, U1> {
TypedSize2D::new(self.width / scale.get(), self.height / scale.get())
fn div(self, scale: Scale<T, U1, U2>) -> Size2D<T, U1> {
Size2D::new(self.width / scale.get(), self.height / scale.get())
}
}
impl<T: Copy, U> TypedSize2D<T, U> {
impl<T: Copy, U> Size2D<T, U> {
/// Returns self.width as a Length carrying the unit.
#[inline]
pub fn width_typed(&self) -> Length<T, U> {
Length::new(self.width)
}
/// Returns self.height as a Length carrying the unit.
#[inline]
pub fn height_typed(&self) -> Length<T, U> {
Length::new(self.height)
}
#[inline]
pub fn to_array(&self) -> [T; 2] {
[self.width, self.height]
@ -211,28 +252,28 @@ impl<T: Copy, U> TypedSize2D<T, U> {
}
#[inline]
pub fn to_vector(&self) -> TypedVector2D<T, U> {
pub fn to_vector(&self) -> Vector2D<T, U> {
vec2(self.width, self.height)
}
/// Drop the units, preserving only the numeric value.
pub fn to_untyped(&self) -> Size2D<T> {
TypedSize2D::new(self.width, self.height)
pub fn to_untyped(&self) -> Size2D<T, UnknownUnit> {
Size2D::new(self.width, self.height)
}
/// Tag a unitless value with units.
pub fn from_untyped(p: &Size2D<T>) -> Self {
TypedSize2D::new(p.width, p.height)
pub fn from_untyped(p: Size2D<T, UnknownUnit>) -> Self {
Size2D::new(p.width, p.height)
}
}
impl<T: NumCast + Copy, Unit> TypedSize2D<T, Unit> {
impl<T: NumCast + Copy, Unit> Size2D<T, Unit> {
/// Cast from one numeric representation to another, preserving the units.
///
/// 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 cast<NewT: NumCast + Copy>(&self) -> TypedSize2D<NewT, Unit> {
pub fn cast<NewT: NumCast + Copy>(&self) -> Size2D<NewT, Unit> {
self.try_cast().unwrap()
}
@ -241,9 +282,9 @@ impl<T: NumCast + Copy, Unit> TypedSize2D<T, Unit> {
/// 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 + Copy>(&self) -> Option<TypedSize2D<NewT, Unit>> {
pub fn try_cast<NewT: NumCast + Copy>(&self) -> Option<Size2D<NewT, Unit>> {
match (NumCast::from(self.width), NumCast::from(self.height)) {
(Some(w), Some(h)) => Some(TypedSize2D::new(w, h)),
(Some(w), Some(h)) => Some(Size2D::new(w, h)),
_ => None,
}
}
@ -251,12 +292,12 @@ impl<T: NumCast + Copy, Unit> TypedSize2D<T, Unit> {
// Convenience functions for common casts
/// Cast into an `f32` size.
pub fn to_f32(&self) -> TypedSize2D<f32, Unit> {
pub fn to_f32(&self) -> Size2D<f32, Unit> {
self.cast()
}
/// Cast into an `f64` size.
pub fn to_f64(&self) -> TypedSize2D<f64, Unit> {
pub fn to_f64(&self) -> Size2D<f64, Unit> {
self.cast()
}
@ -265,7 +306,7 @@ impl<T: NumCast + Copy, Unit> TypedSize2D<T, Unit> {
/// When casting from floating point sizes, it is worth considering whether
/// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
/// the desired conversion behavior.
pub fn to_usize(&self) -> TypedSize2D<usize, Unit> {
pub fn to_usize(&self) -> Size2D<usize, Unit> {
self.cast()
}
@ -274,7 +315,7 @@ impl<T: NumCast + Copy, Unit> TypedSize2D<T, Unit> {
/// When casting from floating point sizes, it is worth considering whether
/// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
/// the desired conversion behavior.
pub fn to_u32(&self) -> TypedSize2D<u32, Unit> {
pub fn to_u32(&self) -> Size2D<u32, Unit> {
self.cast()
}
@ -283,7 +324,7 @@ impl<T: NumCast + Copy, Unit> TypedSize2D<T, Unit> {
/// When casting from floating point sizes, it is worth considering whether
/// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
/// the desired conversion behavior.
pub fn to_i32(&self) -> TypedSize2D<i32, Unit> {
pub fn to_i32(&self) -> Size2D<i32, Unit> {
self.cast()
}
@ -292,12 +333,12 @@ impl<T: NumCast + Copy, Unit> TypedSize2D<T, Unit> {
/// When casting from floating point sizes, it is worth considering whether
/// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
/// the desired conversion behavior.
pub fn to_i64(&self) -> TypedSize2D<i64, Unit> {
pub fn to_i64(&self) -> Size2D<i64, Unit> {
self.cast()
}
}
impl<T, U> TypedSize2D<T, U>
impl<T, U> Size2D<T, U>
where
T: Signed,
{
@ -310,15 +351,15 @@ where
}
}
impl<T: PartialOrd, U> TypedSize2D<T, U> {
pub fn greater_than(&self, other: &Self) -> BoolVector2D {
impl<T: PartialOrd, U> Size2D<T, U> {
pub fn greater_than(&self, other: Self) -> BoolVector2D {
BoolVector2D {
x: self.width > other.width,
y: self.height > other.height,
}
}
pub fn lower_than(&self, other: &Self) -> BoolVector2D {
pub fn lower_than(&self, other: Self) -> BoolVector2D {
BoolVector2D {
x: self.width < other.width,
y: self.height < other.height,
@ -327,15 +368,15 @@ impl<T: PartialOrd, U> TypedSize2D<T, U> {
}
impl<T: PartialEq, U> TypedSize2D<T, U> {
pub fn equal(&self, other: &Self) -> BoolVector2D {
impl<T: PartialEq, U> Size2D<T, U> {
pub fn equal(&self, other: Self) -> BoolVector2D {
BoolVector2D {
x: self.width == other.width,
y: self.height == other.height,
}
}
pub fn not_equal(&self, other: &Self) -> BoolVector2D {
pub fn not_equal(&self, other: Self) -> BoolVector2D {
BoolVector2D {
x: self.width != other.width,
y: self.height != other.height,
@ -343,7 +384,7 @@ impl<T: PartialEq, U> TypedSize2D<T, U> {
}
}
impl<T: Float, U> TypedSize2D<T, U> {
impl<T: Float, U> Size2D<T, U> {
#[inline]
pub fn min(self, other: Self) -> Self {
size2(
@ -367,15 +408,15 @@ impl<T: Float, U> TypedSize2D<T, U> {
}
/// Shorthand for `TypedSize2D::new(w, h)`.
pub fn size2<T, U>(w: T, h: T) -> TypedSize2D<T, U> {
TypedSize2D::new(w, h)
/// Shorthand for `Size2D::new(w, h)`.
pub fn size2<T, U>(w: T, h: T) -> Size2D<T, U> {
Size2D::new(w, h)
}
#[cfg(feature = "mint")]
impl<T, U> From<mint::Vector2<T>> for TypedSize2D<T, U> {
impl<T, U> From<mint::Vector2<T>> for Size2D<T, U> {
fn from(v: mint::Vector2<T>) -> Self {
TypedSize2D {
Size2D {
width: v.x,
height: v.y,
_unit: PhantomData,
@ -383,7 +424,7 @@ impl<T, U> From<mint::Vector2<T>> for TypedSize2D<T, U> {
}
}
#[cfg(feature = "mint")]
impl<T, U> Into<mint::Vector2<T>> for TypedSize2D<T, U> {
impl<T, U> Into<mint::Vector2<T>> for Size2D<T, U> {
fn into(self) -> mint::Vector2<T> {
mint::Vector2 {
x: self.width,
@ -392,25 +433,35 @@ impl<T, U> Into<mint::Vector2<T>> for TypedSize2D<T, U> {
}
}
impl<T: Copy, U> Into<[T; 2]> for TypedSize2D<T, U> {
impl<T, U> From<Vector2D<T, U>> for Size2D<T, U> {
fn from(v: Vector2D<T, U>) -> Self {
Size2D {
width: v.x,
height: v.y,
_unit: PhantomData,
}
}
}
impl<T: Copy, U> Into<[T; 2]> for Size2D<T, U> {
fn into(self) -> [T; 2] {
self.to_array()
}
}
impl<T: Copy, U> From<[T; 2]> for TypedSize2D<T, U> {
impl<T: Copy, U> From<[T; 2]> for Size2D<T, U> {
fn from(array: [T; 2]) -> Self {
size2(array[0], array[1])
}
}
impl<T: Copy, U> Into<(T, T)> for TypedSize2D<T, U> {
impl<T: Copy, U> Into<(T, T)> for Size2D<T, U> {
fn into(self) -> (T, T) {
self.to_tuple()
}
}
impl<T: Copy, U> From<(T, T)> for TypedSize2D<T, U> {
impl<T: Copy, U> From<(T, T)> for Size2D<T, U> {
fn from(tuple: (T, T)) -> Self {
size2(tuple.0, tuple.1)
}
@ -418,7 +469,7 @@ impl<T: Copy, U> From<(T, T)> for TypedSize2D<T, U> {
#[cfg(test)]
mod size2d {
use super::Size2D;
use default::Size2D;
#[cfg(feature = "mint")]
use mint;
@ -478,9 +529,8 @@ mod size2d {
}
/// A 3d size tagged with a unit.
#[derive(EuclidMatrix)]
#[repr(C)]
pub struct TypedSize3D<T, U> {
pub struct Size3D<T, U> {
pub width: T,
pub height: T,
pub depth: T,
@ -488,33 +538,84 @@ pub struct TypedSize3D<T, U> {
pub _unit: PhantomData<U>,
}
/// Default 3d size type with no unit.
///
/// `Size3D` provides the same methods as `TypedSize3D`.
pub type Size3D<T> = TypedSize3D<T, UnknownUnit>;
impl<T: Copy, U> Copy for Size3D<T, U> {}
impl<T: fmt::Debug, U> fmt::Debug for TypedSize3D<T, U> {
impl<T: Clone, U> Clone for Size3D<T, U> {
fn clone(&self) -> Self {
Size3D {
width: self.width.clone(),
height: self.height.clone(),
depth: self.depth.clone(),
_unit: PhantomData,
}
}
}
#[cfg(feature = "serde")]
impl<'de, T, U> serde::Deserialize<'de> for Size3D<T, U>
where T: serde::Deserialize<'de>
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: serde::Deserializer<'de>
{
let (width, height, depth) = try!(serde::Deserialize::deserialize(deserializer));
Ok(Size3D { width, height, depth, _unit: PhantomData })
}
}
#[cfg(feature = "serde")]
impl<T, U> serde::Serialize for Size3D<T, U>
where T: serde::Serialize
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: serde::Serializer
{
(&self.width, &self.height, &self.depth).serialize(serializer)
}
}
impl<T, U> Eq for Size3D<T, U> where T: Eq {}
impl<T, U> PartialEq for Size3D<T, U>
where T: PartialEq
{
fn eq(&self, other: &Self) -> bool {
self.width == other.width && self.height == other.height && self.depth == other.depth
}
}
impl<T, U> Hash for Size3D<T, U>
where T: Hash
{
fn hash<H: ::core::hash::Hasher>(&self, h: &mut H) {
self.width.hash(h);
self.height.hash(h);
self.depth.hash(h);
}
}
impl<T: fmt::Debug, U> fmt::Debug for Size3D<T, U> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}×{:?}×{:?}", self.width, self.height, self.depth)
}
}
impl<T: fmt::Display, U> fmt::Display for TypedSize3D<T, U> {
impl<T: fmt::Display, U> fmt::Display for Size3D<T, U> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "({}x{}x{})", self.width, self.height, self.depth)
}
}
impl<T: Default, U> Default for TypedSize3D<T, U> {
impl<T: Default, U> Default for Size3D<T, U> {
fn default() -> Self {
TypedSize3D::new(Default::default(), Default::default(), Default::default())
Size3D::new(Default::default(), Default::default(), Default::default())
}
}
impl<T, U> TypedSize3D<T, U> {
impl<T, U> Size3D<T, U> {
/// Constructor taking scalar values.
pub fn new(width: T, height: T, depth: T) -> Self {
TypedSize3D {
Size3D {
width,
height,
depth,
@ -523,61 +624,61 @@ impl<T, U> TypedSize3D<T, U> {
}
}
impl<T: Clone, U> TypedSize3D<T, U> {
impl<T: Clone, U> Size3D<T, U> {
/// Constructor taking scalar strongly typed lengths.
pub fn from_lengths(width: Length<T, U>, height: Length<T, U>, depth: Length<T, U>) -> Self {
TypedSize3D::new(width.get(), height.get(), depth.get())
Size3D::new(width.get(), height.get(), depth.get())
}
}
impl<T: Round, U> TypedSize3D<T, U> {
impl<T: Round, U> Size3D<T, U> {
/// Rounds each component to the nearest integer value.
///
/// This behavior is preserved for negative values (unlike the basic cast).
pub fn round(&self) -> Self {
TypedSize3D::new(self.width.round(), self.height.round(), self.depth.round())
Size3D::new(self.width.round(), self.height.round(), self.depth.round())
}
}
impl<T: Ceil, U> TypedSize3D<T, U> {
impl<T: Ceil, U> Size3D<T, U> {
/// Rounds each component to the smallest integer equal or greater than the original value.
///
/// This behavior is preserved for negative values (unlike the basic cast).
pub fn ceil(&self) -> Self {
TypedSize3D::new(self.width.ceil(), self.height.ceil(), self.depth.ceil())
Size3D::new(self.width.ceil(), self.height.ceil(), self.depth.ceil())
}
}
impl<T: Floor, U> TypedSize3D<T, U> {
impl<T: Floor, U> Size3D<T, U> {
/// Rounds each component to the biggest integer equal or lower than the original value.
///
/// This behavior is preserved for negative values (unlike the basic cast).
pub fn floor(&self) -> Self {
TypedSize3D::new(self.width.floor(), self.height.floor(), self.depth.floor())
Size3D::new(self.width.floor(), self.height.floor(), self.depth.floor())
}
}
impl<T: Copy + Add<T, Output = T>, U> Add for TypedSize3D<T, U> {
impl<T: Copy + Add<T, Output = T>, U> Add for Size3D<T, U> {
type Output = Self;
fn add(self, other: Self) -> Self {
TypedSize3D::new(self.width + other.width, self.height + other.height, self.depth + other.depth)
Size3D::new(self.width + other.width, self.height + other.height, self.depth + other.depth)
}
}
impl<T: Copy + Sub<T, Output = T>, U> Sub for TypedSize3D<T, U> {
impl<T: Copy + Sub<T, Output = T>, U> Sub for Size3D<T, U> {
type Output = Self;
fn sub(self, other: Self) -> Self {
TypedSize3D::new(self.width - other.width, self.height - other.height, self.depth - other.depth)
Size3D::new(self.width - other.width, self.height - other.height, self.depth - other.depth)
}
}
impl<T: Copy + Clone + Mul<T, Output=T>, U> TypedSize3D<T, U> {
impl<T: Copy + Clone + Mul<T, Output=T>, U> Size3D<T, U> {
pub fn volume(&self) -> T {
self.width * self.height * self.depth
}
}
impl<T, U> TypedSize3D<T, U>
impl<T, U> Size3D<T, U>
where
T: Copy + One + Add<Output = T> + Sub<Output = T> + Mul<Output = T>,
{
@ -595,104 +696,87 @@ where
}
}
impl<T: Zero + PartialOrd, U> TypedSize3D<T, U> {
impl<T: Zero + PartialOrd, U> Size3D<T, U> {
pub fn is_empty_or_negative(&self) -> bool {
let zero = T::zero();
self.width <= zero || self.height <= zero || self.depth <= zero
}
}
impl<T: Zero, U> TypedSize3D<T, U> {
impl<T: Zero, U> Size3D<T, U> {
pub fn zero() -> Self {
TypedSize3D::new(Zero::zero(), Zero::zero(), Zero::zero())
Size3D::new(Zero::zero(), Zero::zero(), Zero::zero())
}
}
impl<T: Zero, U> Zero for TypedSize3D<T, U> {
impl<T: Zero, U> Zero for Size3D<T, U> {
fn zero() -> Self {
TypedSize3D::new(Zero::zero(), Zero::zero(), Zero::zero())
Size3D::new(Zero::zero(), Zero::zero(), Zero::zero())
}
}
impl<T: Copy + Mul<T, Output = T>, U> Mul<T> for TypedSize3D<T, U> {
impl<T: Copy + Mul<T, Output = T>, U> Mul<T> for Size3D<T, U> {
type Output = Self;
#[inline]
fn mul(self, scale: T) -> Self {
TypedSize3D::new(self.width * scale, self.height * scale, self.depth * scale)
Size3D::new(self.width * scale, self.height * scale, self.depth * scale)
}
}
impl<T: Copy + Div<T, Output = T>, U> Div<T> for TypedSize3D<T, U> {
impl<T: Copy + Div<T, Output = T>, U> Div<T> for Size3D<T, U> {
type Output = Self;
#[inline]
fn div(self, scale: T) -> Self {
TypedSize3D::new(self.width / scale, self.height / scale, self.depth / scale)
Size3D::new(self.width / scale, self.height / scale, self.depth / scale)
}
}
impl<T: Copy + Mul<T, Output = T>, U1, U2> Mul<TypedScale<T, U1, U2>> for TypedSize3D<T, U1> {
type Output = TypedSize3D<T, U2>;
impl<T: Copy + Mul<T, Output = T>, U1, U2> Mul<Scale<T, U1, U2>> for Size3D<T, U1> {
type Output = Size3D<T, U2>;
#[inline]
fn mul(self, scale: TypedScale<T, U1, U2>) -> TypedSize3D<T, U2> {
TypedSize3D::new(self.width * scale.get(), self.height * scale.get(), self.depth * scale.get())
fn mul(self, scale: Scale<T, U1, U2>) -> Size3D<T, U2> {
Size3D::new(self.width * scale.get(), self.height * scale.get(), self.depth * scale.get())
}
}
impl<T: Copy + Div<T, Output = T>, U1, U2> Div<TypedScale<T, U1, U2>> for TypedSize3D<T, U2> {
type Output = TypedSize3D<T, U1>;
impl<T: Copy + Div<T, Output = T>, U1, U2> Div<Scale<T, U1, U2>> for Size3D<T, U2> {
type Output = Size3D<T, U1>;
#[inline]
fn div(self, scale: TypedScale<T, U1, U2>) -> TypedSize3D<T, U1> {
TypedSize3D::new(self.width / scale.get(), self.height / scale.get(), self.depth / scale.get())
fn div(self, scale: Scale<T, U1, U2>) -> Size3D<T, U1> {
Size3D::new(self.width / scale.get(), self.height / scale.get(), self.depth / scale.get())
}
}
impl<T: Copy, U> TypedSize3D<T, U> {
impl<T: Copy, U> Size3D<T, U> {
/// Returns self.width as a Length carrying the unit.
#[inline]
pub fn width_typed(&self) -> Length<T, U> {
Length::new(self.width)
}
/// Returns self.height as a Length carrying the unit.
#[inline]
pub fn height_typed(&self) -> Length<T, U> {
Length::new(self.height)
}
/// Returns self.depth as a Length carrying the unit.
#[inline]
pub fn depth_typed(&self) -> Length<T, U> {
Length::new(self.depth)
}
#[inline]
pub fn to_array(&self) -> [T; 3] {
[self.width, self.height, self.depth]
}
#[inline]
pub fn to_vector(&self) -> TypedVector3D<T, U> {
pub fn to_vector(&self) -> Vector3D<T, U> {
vec3(self.width, self.height, self.depth)
}
/// Drop the units, preserving only the numeric value.
pub fn to_untyped(&self) -> Size3D<T> {
TypedSize3D::new(self.width, self.height, self.depth)
pub fn to_untyped(&self) -> Size3D<T, UnknownUnit> {
Size3D::new(self.width, self.height, self.depth)
}
/// Tag a unitless value with units.
pub fn from_untyped(p: &Size3D<T>) -> Self {
TypedSize3D::new(p.width, p.height, p.depth)
pub fn from_untyped(p: Size3D<T, UnknownUnit>) -> Self {
Size3D::new(p.width, p.height, p.depth)
}
}
impl<T: NumCast + Copy, Unit> TypedSize3D<T, Unit> {
impl<T: NumCast + Copy, Unit> Size3D<T, Unit> {
/// Cast from one numeric representation to another, preserving the units.
///
/// 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 cast<NewT: NumCast + Copy>(&self) -> TypedSize3D<NewT, Unit> {
pub fn cast<NewT: NumCast + Copy>(&self) -> Size3D<NewT, Unit> {
self.try_cast().unwrap()
}
@ -701,9 +785,9 @@ impl<T: NumCast + Copy, Unit> TypedSize3D<T, Unit> {
/// 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 + Copy>(&self) -> Option<TypedSize3D<NewT, Unit>> {
pub fn try_cast<NewT: NumCast + Copy>(&self) -> Option<Size3D<NewT, Unit>> {
match (NumCast::from(self.width), NumCast::from(self.height), NumCast::from(self.depth)) {
(Some(w), Some(h), Some(d)) => Some(TypedSize3D::new(w, h, d)),
(Some(w), Some(h), Some(d)) => Some(Size3D::new(w, h, d)),
_ => None,
}
}
@ -711,12 +795,12 @@ impl<T: NumCast + Copy, Unit> TypedSize3D<T, Unit> {
// Convenience functions for common casts
/// Cast into an `f32` size.
pub fn to_f32(&self) -> TypedSize3D<f32, Unit> {
pub fn to_f32(&self) -> Size3D<f32, Unit> {
self.cast()
}
/// Cast into an `f64` size.
pub fn to_f64(&self) -> TypedSize3D<f64, Unit> {
pub fn to_f64(&self) -> Size3D<f64, Unit> {
self.cast()
}
@ -725,7 +809,7 @@ impl<T: NumCast + Copy, Unit> TypedSize3D<T, Unit> {
/// When casting from floating point sizes, it is worth considering whether
/// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
/// the desired conversion behavior.
pub fn to_usize(&self) -> TypedSize3D<usize, Unit> {
pub fn to_usize(&self) -> Size3D<usize, Unit> {
self.cast()
}
@ -734,7 +818,7 @@ impl<T: NumCast + Copy, Unit> TypedSize3D<T, Unit> {
/// When casting from floating point sizes, it is worth considering whether
/// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
/// the desired conversion behavior.
pub fn to_u32(&self) -> TypedSize3D<u32, Unit> {
pub fn to_u32(&self) -> Size3D<u32, Unit> {
self.cast()
}
@ -743,7 +827,7 @@ impl<T: NumCast + Copy, Unit> TypedSize3D<T, Unit> {
/// When casting from floating point sizes, it is worth considering whether
/// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
/// the desired conversion behavior.
pub fn to_i32(&self) -> TypedSize3D<i32, Unit> {
pub fn to_i32(&self) -> Size3D<i32, Unit> {
self.cast()
}
@ -752,12 +836,12 @@ impl<T: NumCast + Copy, Unit> TypedSize3D<T, Unit> {
/// When casting from floating point sizes, it is worth considering whether
/// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
/// the desired conversion behavior.
pub fn to_i64(&self) -> TypedSize3D<i64, Unit> {
pub fn to_i64(&self) -> Size3D<i64, Unit> {
self.cast()
}
}
impl<T, U> TypedSize3D<T, U>
impl<T, U> Size3D<T, U>
where
T: Signed,
{
@ -770,8 +854,8 @@ where
}
}
impl<T: PartialOrd, U> TypedSize3D<T, U> {
pub fn greater_than(&self, other: &Self) -> BoolVector3D {
impl<T: PartialOrd, U> Size3D<T, U> {
pub fn greater_than(&self, other: Self) -> BoolVector3D {
BoolVector3D {
x: self.width > other.width,
y: self.height > other.height,
@ -779,7 +863,7 @@ impl<T: PartialOrd, U> TypedSize3D<T, U> {
}
}
pub fn lower_than(&self, other: &Self) -> BoolVector3D {
pub fn lower_than(&self, other: Self) -> BoolVector3D {
BoolVector3D {
x: self.width < other.width,
y: self.height < other.height,
@ -789,8 +873,8 @@ impl<T: PartialOrd, U> TypedSize3D<T, U> {
}
impl<T: PartialEq, U> TypedSize3D<T, U> {
pub fn equal(&self, other: &Self) -> BoolVector3D {
impl<T: PartialEq, U> Size3D<T, U> {
pub fn equal(&self, other: Self) -> BoolVector3D {
BoolVector3D {
x: self.width == other.width,
y: self.height == other.height,
@ -798,7 +882,7 @@ impl<T: PartialEq, U> TypedSize3D<T, U> {
}
}
pub fn not_equal(&self, other: &Self) -> BoolVector3D {
pub fn not_equal(&self, other: Self) -> BoolVector3D {
BoolVector3D {
x: self.width != other.width,
y: self.height != other.height,
@ -807,7 +891,7 @@ impl<T: PartialEq, U> TypedSize3D<T, U> {
}
}
impl<T: Float, U> TypedSize3D<T, U> {
impl<T: Float, U> Size3D<T, U> {
#[inline]
pub fn min(self, other: Self) -> Self {
size3(
@ -833,15 +917,15 @@ impl<T: Float, U> TypedSize3D<T, U> {
}
/// Shorthand for `TypedSize3D::new(w, h, d)`.
pub fn size3<T, U>(w: T, h: T, d: T) -> TypedSize3D<T, U> {
TypedSize3D::new(w, h, d)
/// Shorthand for `Size3D::new(w, h, d)`.
pub fn size3<T, U>(w: T, h: T, d: T) -> Size3D<T, U> {
Size3D::new(w, h, d)
}
#[cfg(feature = "mint")]
impl<T, U> From<mint::Vector3<T>> for TypedSize3D<T, U> {
impl<T, U> From<mint::Vector3<T>> for Size3D<T, U> {
fn from(v: mint::Vector3<T>) -> Self {
TypedSize3D {
Size3D {
width: v.x,
height: v.y,
depth: v.z,
@ -850,7 +934,7 @@ impl<T, U> From<mint::Vector3<T>> for TypedSize3D<T, U> {
}
}
#[cfg(feature = "mint")]
impl<T, U> Into<mint::Vector3<T>> for TypedSize3D<T, U> {
impl<T, U> Into<mint::Vector3<T>> for Size3D<T, U> {
fn into(self) -> mint::Vector3<T> {
mint::Vector3 {
x: self.width,

290
third_party/rust/euclid/src/transform2d.rs поставляемый
Просмотреть файл

@ -13,23 +13,27 @@ use super::{UnknownUnit, Angle};
#[cfg(feature = "mint")]
use mint;
use num::{One, Zero};
use point::TypedPoint2D;
use vector::{TypedVector2D, vec2};
use rect::TypedRect;
use transform3d::TypedTransform3D;
use point::{Point2D, point2};
use vector::{Vector2D, vec2};
use rect::Rect;
use transform3d::Transform3D;
use core::ops::{Add, Mul, Div, Sub, Neg};
use core::marker::PhantomData;
use core::cmp::{Eq, PartialEq};
use core::hash::{Hash};
use approxeq::ApproxEq;
use trig::Trig;
use core::fmt;
use num_traits::NumCast;
#[cfg(feature = "serde")]
use serde;
/// A 2d transform stored as a 3 by 2 matrix in row-major order in memory.
///
/// Transforms can be parametrized over the source and destination units, to describe a
/// transformation from a space to another.
/// For example, `TypedTransform2D<f32, WorldSpace, ScreenSpace>::transform_point4d`
/// takes a `TypedPoint2D<f32, WorldSpace>` and returns a `TypedPoint2D<f32, ScreenSpace>`.
/// For example, `Transform2D<f32, WorldSpace, ScreenSpace>::transform_point4d`
/// takes a `Point2D<f32, WorldSpace>` and returns a `Point2D<f32, ScreenSpace>`.
///
/// Transforms expose a set of convenience methods for pre- and post-transformations.
/// A pre-transformation corresponds to adding an operation that is applied before
@ -40,8 +44,7 @@ use num_traits::NumCast;
/// a vector is `v * T`. If your library is using column vectors, use `row_major` functions when you
/// are asked for `column_major` representations and vice versa.
#[repr(C)]
#[derive(EuclidMatrix)]
pub struct TypedTransform2D<T, Src, Dst> {
pub struct Transform2D<T, Src, Dst> {
pub m11: T, pub m12: T,
pub m21: T, pub m22: T,
pub m31: T, pub m32: T,
@ -49,17 +52,94 @@ pub struct TypedTransform2D<T, Src, Dst> {
pub _unit: PhantomData<(Src, Dst)>,
}
/// The default 2d transform type with no units.
pub type Transform2D<T> = TypedTransform2D<T, UnknownUnit, UnknownUnit>;
impl<T: Copy, Src, Dst> Copy for Transform2D<T, Src, Dst> {}
impl<T: Copy, Src, Dst> TypedTransform2D<T, Src, Dst> {
impl<T: Clone, Src, Dst> Clone for Transform2D<T, Src, Dst> {
fn clone(&self) -> Self {
Transform2D {
m11: self.m11.clone(),
m12: self.m12.clone(),
m21: self.m21.clone(),
m22: self.m22.clone(),
m31: self.m31.clone(),
m32: self.m32.clone(),
_unit: PhantomData,
}
}
}
#[cfg(feature = "serde")]
impl<'de, T, Src, Dst> serde::Deserialize<'de> for Transform2D<T, Src, Dst>
where T: serde::Deserialize<'de>
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: serde::Deserializer<'de>
{
let (
m11, m12,
m21, m22,
m31, m32,
) = try!(serde::Deserialize::deserialize(deserializer));
Ok(Transform2D {
m11, m12,
m21, m22,
m31, m32,
_unit: PhantomData
})
}
}
#[cfg(feature = "serde")]
impl<T, Src, Dst> serde::Serialize for Transform2D<T, Src, Dst>
where T: serde::Serialize
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: serde::Serializer
{
(
&self.m11, &self.m12,
&self.m21, &self.m22,
&self.m31, &self.m32,
).serialize(serializer)
}
}
impl<T, Src, Dst> Eq for Transform2D<T, Src, Dst> where T: Eq {}
impl<T, Src, Dst> PartialEq for Transform2D<T, Src, Dst>
where T: PartialEq
{
fn eq(&self, other: &Self) -> bool {
self.m11 == other.m11 &&
self.m12 == other.m12 &&
self.m21 == other.m21 &&
self.m22 == other.m22 &&
self.m31 == other.m31 &&
self.m32 == other.m32
}
}
impl<T, Src, Dst> Hash for Transform2D<T, Src, Dst>
where T: Hash
{
fn hash<H: ::core::hash::Hasher>(&self, h: &mut H) {
self.m11.hash(h);
self.m12.hash(h);
self.m21.hash(h);
self.m22.hash(h);
self.m31.hash(h);
self.m32.hash(h);
}
}
impl<T: Copy, Src, Dst> Transform2D<T, Src, Dst> {
/// Create a transform specifying its matrix elements in row-major order.
///
/// Beware: This library is written with the assumption that row vectors
/// are being used. If your matrices use column vectors (i.e. transforming a vector
/// is `T * v`), then please use `column_major`
pub fn row_major(m11: T, m12: T, m21: T, m22: T, m31: T, m32: T) -> Self {
TypedTransform2D {
Transform2D {
m11, m12,
m21, m22,
m31, m32,
@ -73,7 +153,7 @@ impl<T: Copy, Src, Dst> TypedTransform2D<T, Src, Dst> {
/// are being used. If your matrices use column vectors (i.e. transforming a vector
/// is `T * v`), then please use `row_major`
pub fn column_major(m11: T, m21: T, m31: T, m12: T, m22: T, m32: T) -> Self {
TypedTransform2D {
Transform2D {
m11, m12,
m21, m22,
m31, m32,
@ -150,7 +230,7 @@ impl<T: Copy, Src, Dst> TypedTransform2D<T, Src, Dst> {
}
/// Drop the units, preserving only the numeric value.
pub fn to_untyped(&self) -> Transform2D<T> {
pub fn to_untyped(&self) -> Transform2D<T, UnknownUnit, UnknownUnit> {
Transform2D::row_major(
self.m11, self.m12,
self.m21, self.m22,
@ -159,8 +239,8 @@ impl<T: Copy, Src, Dst> TypedTransform2D<T, Src, Dst> {
}
/// Tag a unitless value with units.
pub fn from_untyped(p: &Transform2D<T>) -> Self {
TypedTransform2D::row_major(
pub fn from_untyped(p: &Transform2D<T, UnknownUnit, UnknownUnit>) -> Self {
Transform2D::row_major(
p.m11, p.m12,
p.m21, p.m22,
p.m31, p.m32
@ -168,21 +248,21 @@ impl<T: Copy, Src, Dst> TypedTransform2D<T, Src, Dst> {
}
}
impl<T0: NumCast + Copy, Src, Dst> TypedTransform2D<T0, Src, Dst> {
impl<T0: NumCast + Copy, Src, Dst> Transform2D<T0, Src, Dst> {
/// Cast from one numeric representation to another, preserving the units.
pub fn cast<T1: NumCast + Copy>(&self) -> TypedTransform2D<T1, Src, Dst> {
pub fn cast<T1: NumCast + Copy>(&self) -> Transform2D<T1, Src, Dst> {
self.try_cast().unwrap()
}
/// Fallible cast from one numeric representation to another, preserving the units.
pub fn try_cast<T1: NumCast + Copy>(&self) -> Option<TypedTransform2D<T1, Src, Dst>> {
pub fn try_cast<T1: NumCast + Copy>(&self) -> Option<Transform2D<T1, Src, Dst>> {
match (NumCast::from(self.m11), NumCast::from(self.m12),
NumCast::from(self.m21), NumCast::from(self.m22),
NumCast::from(self.m31), NumCast::from(self.m32)) {
(Some(m11), Some(m12),
Some(m21), Some(m22),
Some(m31), Some(m32)) => {
Some(TypedTransform2D::row_major(
Some(Transform2D::row_major(
m11, m12,
m21, m22,
m31, m32
@ -193,13 +273,13 @@ impl<T0: NumCast + Copy, Src, Dst> TypedTransform2D<T0, Src, Dst> {
}
}
impl<T, Src, Dst> TypedTransform2D<T, Src, Dst>
impl<T, Src, Dst> Transform2D<T, Src, Dst>
where T: Copy +
PartialEq +
One + Zero {
pub fn identity() -> Self {
let (_0, _1) = (Zero::zero(), One::one());
TypedTransform2D::row_major(
Transform2D::row_major(
_1, _0,
_0, _1,
_0, _0
@ -210,11 +290,11 @@ where T: Copy +
// while most consumers will probably want some sort of approximate
// equivalence to deal with floating-point errors.
fn is_identity(&self) -> bool {
*self == TypedTransform2D::identity()
*self == Transform2D::identity()
}
}
impl<T, Src, Dst> TypedTransform2D<T, Src, Dst>
impl<T, Src, Dst> Transform2D<T, Src, Dst>
where T: Copy + Clone +
Add<T, Output=T> +
Mul<T, Output=T> +
@ -228,9 +308,9 @@ where T: Copy + Clone +
/// applies after self's transformation.
///
/// Assuming row vectors, this is equivalent to self * mat
#[cfg_attr(feature = "unstable", must_use)]
pub fn post_mul<NewDst>(&self, mat: &TypedTransform2D<T, Dst, NewDst>) -> TypedTransform2D<T, Src, NewDst> {
TypedTransform2D::row_major(
#[must_use]
pub fn post_transform<NewDst>(&self, mat: &Transform2D<T, Dst, NewDst>) -> Transform2D<T, Src, NewDst> {
Transform2D::row_major(
self.m11 * mat.m11 + self.m12 * mat.m21,
self.m11 * mat.m12 + self.m12 * mat.m22,
self.m21 * mat.m11 + self.m22 * mat.m21,
@ -244,15 +324,17 @@ where T: Copy + Clone +
/// applies before self's transformation.
///
/// Assuming row vectors, this is equivalent to mat * self
#[cfg_attr(feature = "unstable", must_use)]
pub fn pre_mul<NewSrc>(&self, mat: &TypedTransform2D<T, NewSrc, Src>) -> TypedTransform2D<T, NewSrc, Dst> {
mat.post_mul(self)
#[inline]
#[must_use]
pub fn pre_transform<NewSrc>(&self, mat: &Transform2D<T, NewSrc, Src>) -> Transform2D<T, NewSrc, Dst> {
mat.post_transform(self)
}
/// Returns a translation transform.
#[inline]
pub fn create_translation(x: T, y: T) -> Self {
let (_0, _1): (T, T) = (Zero::zero(), One::one());
TypedTransform2D::row_major(
Transform2D::row_major(
_1, _0,
_0, _1,
x, y
@ -260,21 +342,23 @@ where T: Copy + Clone +
}
/// Applies a translation after self's transformation and returns the resulting transform.
#[cfg_attr(feature = "unstable", must_use)]
pub fn post_translate(&self, v: TypedVector2D<T, Dst>) -> Self {
self.post_mul(&TypedTransform2D::create_translation(v.x, v.y))
#[inline]
#[must_use]
pub fn post_translate(&self, v: Vector2D<T, Dst>) -> Self {
self.post_transform(&Transform2D::create_translation(v.x, v.y))
}
/// Applies a translation before self's transformation and returns the resulting transform.
#[cfg_attr(feature = "unstable", must_use)]
pub fn pre_translate(&self, v: TypedVector2D<T, Src>) -> Self {
self.pre_mul(&TypedTransform2D::create_translation(v.x, v.y))
#[inline]
#[must_use]
pub fn pre_translate(&self, v: Vector2D<T, Src>) -> Self {
self.pre_transform(&Transform2D::create_translation(v.x, v.y))
}
/// Returns a scale transform.
pub fn create_scale(x: T, y: T) -> Self {
let _0 = Zero::zero();
TypedTransform2D::row_major(
Transform2D::row_major(
x, _0,
_0, y,
_0, _0
@ -282,15 +366,17 @@ where T: Copy + Clone +
}
/// Applies a scale after self's transformation and returns the resulting transform.
#[cfg_attr(feature = "unstable", must_use)]
#[inline]
#[must_use]
pub fn post_scale(&self, x: T, y: T) -> Self {
self.post_mul(&TypedTransform2D::create_scale(x, y))
self.post_transform(&Transform2D::create_scale(x, y))
}
/// Applies a scale before self's transformation and returns the resulting transform.
#[cfg_attr(feature = "unstable", must_use)]
#[inline]
#[must_use]
pub fn pre_scale(&self, x: T, y: T) -> Self {
TypedTransform2D::row_major(
Transform2D::row_major(
self.m11 * x, self.m12,
self.m21, self.m22 * y,
self.m31, self.m32
@ -298,11 +384,12 @@ where T: Copy + Clone +
}
/// Returns a rotation transform.
#[inline]
pub fn create_rotation(theta: Angle<T>) -> Self {
let _0 = Zero::zero();
let cos = theta.get().cos();
let sin = theta.get().sin();
TypedTransform2D::row_major(
Transform2D::row_major(
cos, _0 - sin,
sin, cos,
_0, _0
@ -310,33 +397,37 @@ where T: Copy + Clone +
}
/// Applies a rotation after self's transformation and returns the resulting transform.
#[cfg_attr(feature = "unstable", must_use)]
#[inline]
#[must_use]
pub fn post_rotate(&self, theta: Angle<T>) -> Self {
self.post_mul(&TypedTransform2D::create_rotation(theta))
self.post_transform(&Transform2D::create_rotation(theta))
}
/// Applies a rotation after self's transformation and returns the resulting transform.
#[cfg_attr(feature = "unstable", must_use)]
/// Applies a rotation before self's transformation and returns the resulting transform.
#[inline]
#[must_use]
pub fn pre_rotate(&self, theta: Angle<T>) -> Self {
self.pre_mul(&TypedTransform2D::create_rotation(theta))
self.pre_transform(&Transform2D::create_rotation(theta))
}
/// Returns the given point transformed by this transform.
///
/// Assuming row vectors, this is equivalent to `p * self`
#[inline]
#[cfg_attr(feature = "unstable", must_use)]
pub fn transform_point(&self, point: &TypedPoint2D<T, Src>) -> TypedPoint2D<T, Dst> {
TypedPoint2D::new(point.x * self.m11 + point.y * self.m21 + self.m31,
point.x * self.m12 + point.y * self.m22 + self.m32)
#[must_use]
pub fn transform_point(&self, point: Point2D<T, Src>) -> Point2D<T, Dst> {
Point2D::new(
point.x * self.m11 + point.y * self.m21 + self.m31,
point.x * self.m12 + point.y * self.m22 + self.m32
)
}
/// Returns the given vector transformed by this matrix.
///
/// Assuming row vectors, this is equivalent to `v * self`
#[inline]
#[cfg_attr(feature = "unstable", must_use)]
pub fn transform_vector(&self, vec: &TypedVector2D<T, Src>) -> TypedVector2D<T, Dst> {
#[must_use]
pub fn transform_vector(&self, vec: Vector2D<T, Src>) -> Vector2D<T, Dst> {
vec2(vec.x * self.m11 + vec.y * self.m21,
vec.x * self.m12 + vec.y * self.m22)
}
@ -344,13 +435,15 @@ where T: Copy + Clone +
/// Returns a rectangle that encompasses the result of transforming the given rectangle by this
/// transform.
#[inline]
#[cfg_attr(feature = "unstable", must_use)]
pub fn transform_rect(&self, rect: &TypedRect<T, Src>) -> TypedRect<T, Dst> {
TypedRect::from_points(&[
self.transform_point(&rect.origin),
self.transform_point(&rect.top_right()),
self.transform_point(&rect.bottom_left()),
self.transform_point(&rect.bottom_right()),
#[must_use]
pub fn transform_rect(&self, rect: &Rect<T, Src>) -> Rect<T, Dst> {
let min = rect.min();
let max = rect.max();
Rect::from_points(&[
self.transform_point(min),
self.transform_point(max),
self.transform_point(point2(max.x, min.y)),
self.transform_point(point2(min.x, max.y)),
])
}
@ -360,8 +453,8 @@ where T: Copy + Clone +
}
/// Returns the inverse transform if possible.
#[cfg_attr(feature = "unstable", must_use)]
pub fn inverse(&self) -> Option<TypedTransform2D<T, Dst, Src>> {
#[must_use]
pub fn inverse(&self) -> Option<Transform2D<T, Dst, Src>> {
let det = self.determinant();
let _0: T = Zero::zero();
@ -372,7 +465,7 @@ where T: Copy + Clone +
}
let inv_det = _1 / det;
Some(TypedTransform2D::row_major(
Some(Transform2D::row_major(
inv_det * self.m22,
inv_det * (_0 - self.m12),
inv_det * (_0 - self.m21),
@ -384,8 +477,8 @@ where T: Copy + Clone +
/// Returns the same transform with a different destination unit.
#[inline]
pub fn with_destination<NewDst>(&self) -> TypedTransform2D<T, Src, NewDst> {
TypedTransform2D::row_major(
pub fn with_destination<NewDst>(&self) -> Transform2D<T, Src, NewDst> {
Transform2D::row_major(
self.m11, self.m12,
self.m21, self.m22,
self.m31, self.m32,
@ -394,8 +487,8 @@ where T: Copy + Clone +
/// Returns the same transform with a different source unit.
#[inline]
pub fn with_source<NewSrc>(&self) -> TypedTransform2D<T, NewSrc, Dst> {
TypedTransform2D::row_major(
pub fn with_source<NewSrc>(&self) -> Transform2D<T, NewSrc, Dst> {
Transform2D::row_major(
self.m11, self.m12,
self.m21, self.m22,
self.m31, self.m32,
@ -403,7 +496,7 @@ where T: Copy + Clone +
}
}
impl <T, Src, Dst> TypedTransform2D<T, Src, Dst>
impl <T, Src, Dst> Transform2D<T, Src, Dst>
where T: Copy + Clone +
Add<T, Output=T> +
Sub<T, Output=T> +
@ -414,13 +507,13 @@ where T: Copy + Clone +
Trig +
One + Zero {
/// Create a 3D transform from the current transform
pub fn to_3d(&self) -> TypedTransform3D<T, Src, Dst> {
TypedTransform3D::row_major_2d(self.m11, self.m12, self.m21, self.m22, self.m31, self.m32)
pub fn to_3d(&self) -> Transform3D<T, Src, Dst> {
Transform3D::row_major_2d(self.m11, self.m12, self.m21, self.m22, self.m31, self.m32)
}
}
impl <T, Src, Dst> Default for TypedTransform2D<T, Src, Dst>
impl <T, Src, Dst> Default for Transform2D<T, Src, Dst>
where T: Copy + PartialEq + One + Zero
{
fn default() -> Self {
@ -428,7 +521,7 @@ impl <T, Src, Dst> Default for TypedTransform2D<T, Src, Dst>
}
}
impl<T: ApproxEq<T>, Src, Dst> TypedTransform2D<T, Src, Dst> {
impl<T: ApproxEq<T>, Src, Dst> Transform2D<T, Src, Dst> {
pub fn approx_eq(&self, other: &Self) -> bool {
self.m11.approx_eq(&other.m11) && self.m12.approx_eq(&other.m12) &&
self.m21.approx_eq(&other.m21) && self.m22.approx_eq(&other.m22) &&
@ -436,7 +529,7 @@ impl<T: ApproxEq<T>, Src, Dst> TypedTransform2D<T, Src, Dst> {
}
}
impl<T: Copy + fmt::Debug, Src, Dst> fmt::Debug for TypedTransform2D<T, Src, Dst>
impl<T: Copy + fmt::Debug, Src, Dst> fmt::Debug for Transform2D<T, Src, Dst>
where T: Copy + fmt::Debug +
PartialEq +
One + Zero {
@ -450,9 +543,9 @@ where T: Copy + fmt::Debug +
}
#[cfg(feature = "mint")]
impl<T, Src, Dst> From<mint::RowMatrix3x2<T>> for TypedTransform2D<T, Src, Dst> {
impl<T, Src, Dst> From<mint::RowMatrix3x2<T>> for Transform2D<T, Src, Dst> {
fn from(m: mint::RowMatrix3x2<T>) -> Self {
TypedTransform2D {
Transform2D {
m11: m.x.x, m12: m.x.y,
m21: m.y.x, m22: m.y.y,
m31: m.z.x, m32: m.z.y,
@ -461,7 +554,7 @@ impl<T, Src, Dst> From<mint::RowMatrix3x2<T>> for TypedTransform2D<T, Src, Dst>
}
}
#[cfg(feature = "mint")]
impl<T, Src, Dst> Into<mint::RowMatrix3x2<T>> for TypedTransform2D<T, Src, Dst> {
impl<T, Src, Dst> Into<mint::RowMatrix3x2<T>> for Transform2D<T, Src, Dst> {
fn into(self) -> mint::RowMatrix3x2<T> {
mint::RowMatrix3x2 {
x: mint::Vector2 { x: self.m11, y: self.m12 },
@ -475,15 +568,14 @@ impl<T, Src, Dst> Into<mint::RowMatrix3x2<T>> for TypedTransform2D<T, Src, Dst>
#[cfg(test)]
mod test {
use super::*;
use default;
use approxeq::ApproxEq;
use point::Point2D;
use Angle;
#[cfg(feature = "mint")]
use mint;
use core::f32::consts::FRAC_PI_2;
type Mat = Transform2D<f32>;
type Mat = default::Transform2D<f32>;
fn rad(v: f32) -> Angle<f32> { Angle::radians(v) }
@ -495,9 +587,9 @@ mod test {
assert_eq!(t1, t2);
assert_eq!(t1, t3);
assert_eq!(t1.transform_point(&Point2D::new(1.0, 1.0)), Point2D::new(2.0, 3.0));
assert_eq!(t1.transform_point(Point2D::new(1.0, 1.0)), Point2D::new(2.0, 3.0));
assert_eq!(t1.post_mul(&t1), Mat::create_translation(2.0, 4.0));
assert_eq!(t1.post_transform(&t1), Mat::create_translation(2.0, 4.0));
}
#[test]
@ -508,9 +600,9 @@ mod test {
assert_eq!(r1, r2);
assert_eq!(r1, r3);
assert!(r1.transform_point(&Point2D::new(1.0, 2.0)).approx_eq(&Point2D::new(2.0, -1.0)));
assert!(r1.transform_point(Point2D::new(1.0, 2.0)).approx_eq(&Point2D::new(2.0, -1.0)));
assert!(r1.post_mul(&r1).approx_eq(&Mat::create_rotation(rad(FRAC_PI_2*2.0))));
assert!(r1.post_transform(&r1).approx_eq(&Mat::create_rotation(rad(FRAC_PI_2*2.0))));
}
#[test]
@ -521,7 +613,7 @@ mod test {
assert_eq!(s1, s2);
assert_eq!(s1, s3);
assert!(s1.transform_point(&Point2D::new(2.0, 2.0)).approx_eq(&Point2D::new(4.0, 6.0)));
assert!(s1.transform_point(Point2D::new(2.0, 2.0)).approx_eq(&Point2D::new(4.0, 6.0)));
}
#[test]
@ -550,14 +642,14 @@ mod test {
pub fn test_inverse_scale() {
let m1 = Mat::create_scale(1.5, 0.3);
let m2 = m1.inverse().unwrap();
assert!(m1.pre_mul(&m2).approx_eq(&Mat::identity()));
assert!(m1.pre_transform(&m2).approx_eq(&Mat::identity()));
}
#[test]
pub fn test_inverse_translate() {
let m1 = Mat::create_translation(-132.0, 0.3);
let m2 = m1.inverse().unwrap();
assert!(m1.pre_mul(&m2).approx_eq(&Mat::identity()));
assert!(m1.pre_transform(&m2).approx_eq(&Mat::identity()));
}
#[test]
@ -568,8 +660,8 @@ mod test {
#[test]
pub fn test_pre_post() {
let m1 = Transform2D::identity().post_scale(1.0, 2.0).post_translate(vec2(1.0, 2.0));
let m2 = Transform2D::identity().pre_translate(vec2(1.0, 2.0)).pre_scale(1.0, 2.0);
let m1 = default::Transform2D::identity().post_scale(1.0, 2.0).post_translate(vec2(1.0, 2.0));
let m2 = default::Transform2D::identity().pre_translate(vec2(1.0, 2.0)).pre_scale(1.0, 2.0);
assert!(m1.approx_eq(&m2));
let r = Mat::create_rotation(rad(FRAC_PI_2));
@ -577,25 +669,25 @@ mod test {
let a = Point2D::new(1.0, 1.0);
assert!(r.post_mul(&t).transform_point(&a).approx_eq(&Point2D::new(3.0, 2.0)));
assert!(t.post_mul(&r).transform_point(&a).approx_eq(&Point2D::new(4.0, -3.0)));
assert!(t.post_mul(&r).transform_point(&a).approx_eq(&r.transform_point(&t.transform_point(&a))));
assert!(r.post_transform(&t).transform_point(a).approx_eq(&Point2D::new(3.0, 2.0)));
assert!(t.post_transform(&r).transform_point(a).approx_eq(&Point2D::new(4.0, -3.0)));
assert!(t.post_transform(&r).transform_point(a).approx_eq(&r.transform_point(t.transform_point(a))));
assert!(r.pre_mul(&t).transform_point(&a).approx_eq(&Point2D::new(4.0, -3.0)));
assert!(t.pre_mul(&r).transform_point(&a).approx_eq(&Point2D::new(3.0, 2.0)));
assert!(t.pre_mul(&r).transform_point(&a).approx_eq(&t.transform_point(&r.transform_point(&a))));
assert!(r.pre_transform(&t).transform_point(a).approx_eq(&Point2D::new(4.0, -3.0)));
assert!(t.pre_transform(&r).transform_point(a).approx_eq(&Point2D::new(3.0, 2.0)));
assert!(t.pre_transform(&r).transform_point(a).approx_eq(&t.transform_point(r.transform_point(a))));
}
#[test]
fn test_size_of() {
use core::mem::size_of;
assert_eq!(size_of::<Transform2D<f32>>(), 6*size_of::<f32>());
assert_eq!(size_of::<Transform2D<f64>>(), 6*size_of::<f64>());
assert_eq!(size_of::<default::Transform2D<f32>>(), 6*size_of::<f32>());
assert_eq!(size_of::<default::Transform2D<f64>>(), 6*size_of::<f64>());
}
#[test]
pub fn test_is_identity() {
let m1 = Transform2D::identity();
let m1 = default::Transform2D::identity();
assert!(m1.is_identity());
let m2 = m1.post_translate(vec2(0.1, 0.0));
assert!(!m2.is_identity());
@ -606,7 +698,7 @@ mod test {
// Translation does not apply to vectors.
let m1 = Mat::create_translation(1.0, 1.0);
let v1 = vec2(10.0, -10.0);
assert_eq!(v1, m1.transform_vector(&v1));
assert_eq!(v1, m1.transform_vector(v1));
}
#[cfg(feature = "mint")]

365
third_party/rust/euclid/src/transform3d.rs поставляемый
Просмотреть файл

@ -15,23 +15,27 @@ use homogen::HomogeneousVector;
#[cfg(feature = "mint")]
use mint;
use trig::Trig;
use point::{TypedPoint2D, TypedPoint3D};
use vector::{TypedVector2D, TypedVector3D, vec2, vec3};
use rect::TypedRect;
use transform2d::TypedTransform2D;
use scale::TypedScale;
use point::{Point2D, point2, Point3D};
use vector::{Vector2D, Vector3D, vec2, vec3};
use rect::Rect;
use transform2d::Transform2D;
use scale::Scale;
use num::{One, Zero};
use core::ops::{Add, Mul, Sub, Div, Neg};
use core::marker::PhantomData;
use core::fmt;
use core::cmp::{Eq, PartialEq};
use core::hash::{Hash};
use num_traits::NumCast;
#[cfg(feature = "serde")]
use serde;
/// A 3d transform stored as a 4 by 4 matrix in row-major order in memory.
///
/// Transforms can be parametrized over the source and destination units, to describe a
/// transformation from a space to another.
/// For example, `TypedTransform3D<f32, WorldSpace, ScreenSpace>::transform_point3d`
/// takes a `TypedPoint3D<f32, WorldSpace>` and returns a `TypedPoint3D<f32, ScreenSpace>`.
/// For example, `Transform3D<f32, WorldSpace, ScreenSpace>::transform_point3d`
/// takes a `Point3D<f32, WorldSpace>` and returns a `Point3D<f32, ScreenSpace>`.
///
/// Transforms expose a set of convenience methods for pre- and post-transformations.
/// A pre-transformation corresponds to adding an operation that is applied before
@ -41,9 +45,8 @@ use num_traits::NumCast;
/// These transforms are for working with _row vectors_, so the matrix math for transforming
/// a vector is `v * T`. If your library is using column vectors, use `row_major` functions when you
/// are asked for `column_major` representations and vice versa.
#[derive(EuclidMatrix)]
#[repr(C)]
pub struct TypedTransform3D<T, Src, Dst> {
pub struct Transform3D<T, Src, Dst> {
pub m11: T, pub m12: T, pub m13: T, pub m14: T,
pub m21: T, pub m22: T, pub m23: T, pub m24: T,
pub m31: T, pub m32: T, pub m33: T, pub m34: T,
@ -52,10 +55,120 @@ pub struct TypedTransform3D<T, Src, Dst> {
pub _unit: PhantomData<(Src, Dst)>,
}
/// The default 3d transform type with no units.
pub type Transform3D<T> = TypedTransform3D<T, UnknownUnit, UnknownUnit>;
impl<T: Copy, Src, Dst> Copy for Transform3D<T, Src, Dst> {}
impl<T, Src, Dst> TypedTransform3D<T, Src, Dst> {
impl<T: Clone, Src, Dst> Clone for Transform3D<T, Src, Dst> {
fn clone(&self) -> Self {
Transform3D {
m11: self.m11.clone(),
m12: self.m12.clone(),
m13: self.m13.clone(),
m14: self.m14.clone(),
m21: self.m21.clone(),
m22: self.m22.clone(),
m23: self.m23.clone(),
m24: self.m24.clone(),
m31: self.m31.clone(),
m32: self.m32.clone(),
m33: self.m33.clone(),
m34: self.m34.clone(),
m41: self.m41.clone(),
m42: self.m42.clone(),
m43: self.m43.clone(),
m44: self.m44.clone(),
_unit: PhantomData,
}
}
}
#[cfg(feature = "serde")]
impl<'de, T, Src, Dst> serde::Deserialize<'de> for Transform3D<T, Src, Dst>
where T: serde::Deserialize<'de>
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: serde::Deserializer<'de>
{
let (
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44,
) = try!(serde::Deserialize::deserialize(deserializer));
Ok(Transform3D {
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44,
_unit: PhantomData
})
}
}
#[cfg(feature = "serde")]
impl<T, Src, Dst> serde::Serialize for Transform3D<T, Src, Dst>
where T: serde::Serialize
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: serde::Serializer
{
(
&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,
).serialize(serializer)
}
}
impl<T, Src, Dst> Eq for Transform3D<T, Src, Dst> where T: Eq {}
impl<T, Src, Dst> PartialEq for Transform3D<T, Src, Dst>
where T: PartialEq
{
fn eq(&self, other: &Self) -> bool {
self.m11 == other.m11 &&
self.m12 == other.m12 &&
self.m13 == other.m13 &&
self.m14 == other.m14 &&
self.m21 == other.m21 &&
self.m22 == other.m22 &&
self.m23 == other.m23 &&
self.m24 == other.m24 &&
self.m31 == other.m31 &&
self.m32 == other.m32 &&
self.m33 == other.m33 &&
self.m34 == other.m34 &&
self.m41 == other.m41 &&
self.m42 == other.m42 &&
self.m43 == other.m43 &&
self.m44 == other.m44
}
}
impl<T, Src, Dst> Hash for Transform3D<T, Src, Dst>
where T: Hash
{
fn hash<H: ::core::hash::Hasher>(&self, h: &mut H) {
self.m11.hash(h);
self.m12.hash(h);
self.m13.hash(h);
self.m14.hash(h);
self.m21.hash(h);
self.m22.hash(h);
self.m23.hash(h);
self.m24.hash(h);
self.m31.hash(h);
self.m32.hash(h);
self.m33.hash(h);
self.m34.hash(h);
self.m41.hash(h);
self.m42.hash(h);
self.m43.hash(h);
self.m44.hash(h);
}
}
impl<T, Src, Dst> Transform3D<T, Src, Dst> {
/// Create a transform specifying its components in row-major order.
///
/// For example, the translation terms m41, m42, m43 on the last row with the
@ -72,7 +185,7 @@ impl<T, Src, Dst> TypedTransform3D<T, Src, Dst> {
m31: T, m32: T, m33: T, m34: T,
m41: T, m42: T, m43: T, m44: T)
-> Self {
TypedTransform3D {
Transform3D {
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
@ -97,7 +210,7 @@ impl<T, Src, Dst> TypedTransform3D<T, Src, Dst> {
m13: T, m23: T, m33: T, m43: T,
m14: T, m24: T, m34: T, m44: T)
-> Self {
TypedTransform3D {
Transform3D {
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
@ -107,14 +220,14 @@ impl<T, Src, Dst> TypedTransform3D<T, Src, Dst> {
}
}
impl <T, Src, Dst> TypedTransform3D<T, Src, Dst>
impl <T, Src, Dst> Transform3D<T, Src, Dst>
where T: Copy + Clone +
PartialEq +
One + Zero {
#[inline]
pub fn identity() -> Self {
let (_0, _1): (T, T) = (Zero::zero(), One::one());
TypedTransform3D::row_major(
Transform3D::row_major(
_1, _0, _0, _0,
_0, _1, _0, _0,
_0, _0, _1, _0,
@ -127,11 +240,11 @@ where T: Copy + Clone +
// equivalence to deal with floating-point errors.
#[inline]
fn is_identity(&self) -> bool {
*self == TypedTransform3D::identity()
*self == Transform3D::identity()
}
}
impl <T, Src, Dst> TypedTransform3D<T, Src, Dst>
impl <T, Src, Dst> Transform3D<T, Src, Dst>
where T: Copy + Clone +
Add<T, Output=T> +
Sub<T, Output=T> +
@ -147,7 +260,7 @@ where T: Copy + Clone +
#[inline]
pub fn row_major_2d(m11: T, m12: T, m21: T, m22: T, m41: T, m42: T) -> Self {
let (_0, _1): (T, T) = (Zero::zero(), One::one());
TypedTransform3D::row_major(
Transform3D::row_major(
m11, m12, _0, _0,
m21, m22, _0, _0,
_0, _0, _1, _0,
@ -165,7 +278,7 @@ where T: Copy + Clone +
let (_0, _1): (T, T) = (Zero::zero(), One::one());
let _2 = _1 + _1;
TypedTransform3D::row_major(
Transform3D::row_major(
_2 / (right - left), _0 , _0 , _0,
_0 , _2 / (top - bottom), _0 , _0,
_0 , _0 , -_2 / (far - near), _0,
@ -173,7 +286,7 @@ where T: Copy + Clone +
)
}
/// Returns true if this transform can be represented with a `TypedTransform2D`.
/// Returns true if this transform can be represented with a `Transform2D`.
///
/// See <https://drafts.csswg.org/css-transforms/#2d-transform>
#[inline]
@ -190,8 +303,8 @@ where T: Copy + Clone +
///
/// This method assumes that self represents a 2d transformation, callers
/// should check that self.is_2d() returns true beforehand.
pub fn to_2d(&self) -> TypedTransform2D<T, Src, Dst> {
TypedTransform2D::row_major(
pub fn to_2d(&self) -> Transform2D<T, Src, Dst> {
Transform2D::row_major(
self.m11, self.m12,
self.m21, self.m22,
self.m41, self.m42
@ -224,8 +337,8 @@ where T: Copy + Clone +
/// Returns the same transform with a different destination unit.
#[inline]
pub fn with_destination<NewDst>(&self) -> TypedTransform3D<T, Src, NewDst> {
TypedTransform3D::row_major(
pub fn with_destination<NewDst>(&self) -> Transform3D<T, Src, NewDst> {
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,
@ -235,8 +348,8 @@ where T: Copy + Clone +
/// Returns the same transform with a different source unit.
#[inline]
pub fn with_source<NewSrc>(&self) -> TypedTransform3D<T, NewSrc, Dst> {
TypedTransform3D::row_major(
pub fn with_source<NewSrc>(&self) -> Transform3D<T, NewSrc, Dst> {
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,
@ -246,7 +359,7 @@ where T: Copy + Clone +
/// Drop the units, preserving only the numeric value.
#[inline]
pub fn to_untyped(&self) -> Transform3D<T> {
pub fn to_untyped(&self) -> Transform3D<T, UnknownUnit, UnknownUnit> {
Transform3D::row_major(
self.m11, self.m12, self.m13, self.m14,
self.m21, self.m22, self.m23, self.m24,
@ -257,8 +370,8 @@ where T: Copy + Clone +
/// Tag a unitless value with units.
#[inline]
pub fn from_untyped(m: &Transform3D<T>) -> Self {
TypedTransform3D::row_major(
pub fn from_untyped(m: &Transform3D<T, UnknownUnit, UnknownUnit>) -> Self {
Transform3D::row_major(
m.m11, m.m12, m.m13, m.m14,
m.m21, m.m22, m.m23, m.m24,
m.m31, m.m32, m.m33, m.m34,
@ -270,8 +383,9 @@ where T: Copy + Clone +
/// applies after self's transformation.
///
/// Assuming row vectors, this is equivalent to self * mat
pub fn post_mul<NewDst>(&self, mat: &TypedTransform3D<T, Dst, NewDst>) -> TypedTransform3D<T, Src, NewDst> {
TypedTransform3D::row_major(
#[must_use]
pub fn post_transform<NewDst>(&self, mat: &Transform3D<T, Dst, NewDst>) -> Transform3D<T, Src, NewDst> {
Transform3D::row_major(
self.m11 * mat.m11 + self.m12 * mat.m21 + self.m13 * mat.m31 + self.m14 * mat.m41,
self.m11 * mat.m12 + self.m12 * mat.m22 + self.m13 * mat.m32 + self.m14 * mat.m42,
self.m11 * mat.m13 + self.m12 * mat.m23 + self.m13 * mat.m33 + self.m14 * mat.m43,
@ -295,12 +409,14 @@ where T: Copy + Clone +
/// applies before self's transformation.
///
/// Assuming row vectors, this is equivalent to mat * self
pub fn pre_mul<NewSrc>(&self, mat: &TypedTransform3D<T, NewSrc, Src>) -> TypedTransform3D<T, NewSrc, Dst> {
mat.post_mul(self)
#[inline]
#[must_use]
pub fn pre_transform<NewSrc>(&self, mat: &Transform3D<T, NewSrc, Src>) -> Transform3D<T, NewSrc, Dst> {
mat.post_transform(self)
}
/// Returns the inverse transform if possible.
pub fn inverse(&self) -> Option<TypedTransform3D<T, Dst, Src>> {
pub fn inverse(&self) -> Option<Transform3D<T, Dst, Src>> {
let det = self.determinant();
if det == Zero::zero() {
@ -309,7 +425,7 @@ where T: Copy + Clone +
// todo(gw): this could be made faster by special casing
// for simpler transform types.
let m = TypedTransform3D::row_major(
let m = Transform3D::row_major(
self.m23*self.m34*self.m42 - self.m24*self.m33*self.m42 +
self.m24*self.m32*self.m43 - self.m22*self.m34*self.m43 -
self.m23*self.m32*self.m44 + self.m22*self.m33*self.m44,
@ -408,9 +524,9 @@ where T: Copy + Clone +
}
/// Multiplies all of the transform's component by a scalar and returns the result.
#[cfg_attr(feature = "unstable", must_use)]
#[must_use]
pub fn mul_s(&self, x: T) -> Self {
TypedTransform3D::row_major(
Transform3D::row_major(
self.m11 * x, self.m12 * x, self.m13 * x, self.m14 * x,
self.m21 * x, self.m22 * x, self.m23 * x, self.m24 * x,
self.m31 * x, self.m32 * x, self.m33 * x, self.m34 * x,
@ -418,9 +534,9 @@ where T: Copy + Clone +
)
}
/// Convenience function to create a scale transform from a `TypedScale`.
pub fn from_scale(scale: TypedScale<T, Src, Dst>) -> Self {
TypedTransform3D::create_scale(scale.get(), scale.get(), scale.get())
/// Convenience function to create a scale transform from a `Scale`.
pub fn from_scale(scale: Scale<T, Src, Dst>) -> Self {
Transform3D::create_scale(scale.get(), scale.get(), scale.get())
}
/// Returns the homogeneous vector corresponding to the transformed 2d point.
@ -430,7 +546,7 @@ where T: Copy + Clone +
/// Assuming row vectors, this is equivalent to `p * self`
#[inline]
pub fn transform_point2d_homogeneous(
&self, p: &TypedPoint2D<T, Src>
&self, p: Point2D<T, Src>
) -> HomogeneousVector<T, Dst> {
let x = p.x * self.m11 + p.y * self.m21 + self.m41;
let y = p.x * self.m12 + p.y * self.m22 + self.m42;
@ -447,14 +563,14 @@ where T: Copy + Clone +
///
/// Assuming row vectors, this is equivalent to `p * self`
#[inline]
pub fn transform_point2d(&self, p: &TypedPoint2D<T, Src>) -> Option<TypedPoint2D<T, Dst>> {
pub fn transform_point2d(&self, p: Point2D<T, Src>) -> Option<Point2D<T, Dst>> {
//Note: could use `transform_point2d_homogeneous()` but it would waste the calculus of `z`
let w = p.x * self.m14 + p.y * self.m24 + self.m44;
if w > T::zero() {
let x = p.x * self.m11 + p.y * self.m21 + self.m41;
let y = p.x * self.m12 + p.y * self.m22 + self.m42;
Some(TypedPoint2D::new(x / w, y / w))
Some(Point2D::new(x / w, y / w))
} else {
None
}
@ -466,7 +582,7 @@ where T: Copy + Clone +
///
/// Assuming row vectors, this is equivalent to `v * self`
#[inline]
pub fn transform_vector2d(&self, v: &TypedVector2D<T, Src>) -> TypedVector2D<T, Dst> {
pub fn transform_vector2d(&self, v: Vector2D<T, Src>) -> Vector2D<T, Dst> {
vec2(
v.x * self.m11 + v.y * self.m21,
v.x * self.m12 + v.y * self.m22,
@ -480,7 +596,7 @@ where T: Copy + Clone +
/// Assuming row vectors, this is equivalent to `p * self`
#[inline]
pub fn transform_point3d_homogeneous(
&self, p: &TypedPoint3D<T, Src>
&self, p: Point3D<T, Src>
) -> HomogeneousVector<T, Dst> {
let x = p.x * self.m11 + p.y * self.m21 + p.z * self.m31 + self.m41;
let y = p.x * self.m12 + p.y * self.m22 + p.z * self.m32 + self.m42;
@ -497,7 +613,7 @@ where T: Copy + Clone +
///
/// Assuming row vectors, this is equivalent to `p * self`
#[inline]
pub fn transform_point3d(&self, p: &TypedPoint3D<T, Src>) -> Option<TypedPoint3D<T, Dst>> {
pub fn transform_point3d(&self, p: Point3D<T, Src>) -> Option<Point3D<T, Dst>> {
self.transform_point3d_homogeneous(p).to_point3d()
}
@ -507,7 +623,7 @@ where T: Copy + Clone +
///
/// Assuming row vectors, this is equivalent to `v * self`
#[inline]
pub fn transform_vector3d(&self, v: &TypedVector3D<T, Src>) -> TypedVector3D<T, Dst> {
pub fn transform_vector3d(&self, v: Vector3D<T, Src>) -> Vector3D<T, Dst> {
vec3(
v.x * self.m11 + v.y * self.m21 + v.z * self.m31,
v.x * self.m12 + v.y * self.m22 + v.z * self.m32,
@ -517,19 +633,21 @@ where T: Copy + Clone +
/// Returns a rectangle that encompasses the result of transforming the given rectangle by this
/// transform, if the transform makes sense for it, or `None` otherwise.
pub fn transform_rect(&self, rect: &TypedRect<T, Src>) -> Option<TypedRect<T, Dst>> {
Some(TypedRect::from_points(&[
self.transform_point2d(&rect.origin)?,
self.transform_point2d(&rect.top_right())?,
self.transform_point2d(&rect.bottom_left())?,
self.transform_point2d(&rect.bottom_right())?,
pub fn transform_rect(&self, rect: &Rect<T, Src>) -> Option<Rect<T, Dst>> {
let min = rect.min();
let max = rect.max();
Some(Rect::from_points(&[
self.transform_point2d(min)?,
self.transform_point2d(max)?,
self.transform_point2d(point2(max.x, min.y))?,
self.transform_point2d(point2(min.x, max.y))?,
]))
}
/// Create a 3d translation transform
pub fn create_translation(x: T, y: T, z: T) -> Self {
let (_0, _1): (T, T) = (Zero::zero(), One::one());
TypedTransform3D::row_major(
Transform3D::row_major(
_1, _0, _0, _0,
_0, _1, _0, _0,
_0, _0, _1, _0,
@ -538,15 +656,15 @@ where T: Copy + Clone +
}
/// Returns a transform with a translation applied before self's transformation.
#[cfg_attr(feature = "unstable", must_use)]
pub fn pre_translate(&self, v: TypedVector3D<T, Src>) -> Self {
self.pre_mul(&TypedTransform3D::create_translation(v.x, v.y, v.z))
#[must_use]
pub fn pre_translate(&self, v: Vector3D<T, Src>) -> Self {
self.pre_transform(&Transform3D::create_translation(v.x, v.y, v.z))
}
/// Returns a transform with a translation applied after self's transformation.
#[cfg_attr(feature = "unstable", must_use)]
pub fn post_translate(&self, v: TypedVector3D<T, Dst>) -> Self {
self.post_mul(&TypedTransform3D::create_translation(v.x, v.y, v.z))
#[must_use]
pub fn post_translate(&self, v: Vector3D<T, Dst>) -> Self {
self.post_transform(&Transform3D::create_translation(v.x, v.y, v.z))
}
/// Returns a projection of this transform in 2d space.
@ -588,7 +706,7 @@ where T: Copy + Clone +
/// Create a 3d scale transform
pub fn create_scale(x: T, y: T, z: T) -> Self {
let (_0, _1): (T, T) = (Zero::zero(), One::one());
TypedTransform3D::row_major(
Transform3D::row_major(
x, _0, _0, _0,
_0, y, _0, _0,
_0, _0, z, _0,
@ -597,9 +715,9 @@ where T: Copy + Clone +
}
/// Returns a transform with a scale applied before self's transformation.
#[cfg_attr(feature = "unstable", must_use)]
#[must_use]
pub fn pre_scale(&self, x: T, y: T, z: T) -> Self {
TypedTransform3D::row_major(
Transform3D::row_major(
self.m11 * x, self.m12, self.m13, self.m14,
self.m21 , self.m22 * y, self.m23, self.m24,
self.m31 , self.m32, self.m33 * z, self.m34,
@ -608,9 +726,9 @@ where T: Copy + Clone +
}
/// Returns a transform with a scale applied after self's transformation.
#[cfg_attr(feature = "unstable", must_use)]
#[must_use]
pub fn post_scale(&self, x: T, y: T, z: T) -> Self {
self.post_mul(&TypedTransform3D::create_scale(x, y, z))
self.post_transform(&Transform3D::create_scale(x, y, z))
}
/// Create a 3d rotation transform from an angle / axis.
@ -627,7 +745,7 @@ where T: Copy + Clone +
let sc = half_theta.sin() * half_theta.cos();
let sq = half_theta.sin() * half_theta.sin();
TypedTransform3D::row_major(
Transform3D::row_major(
_1 - _2 * (yy + zz) * sq,
_2 * (x * y * sq - z * sc),
_2 * (x * z * sq + y * sc),
@ -651,15 +769,15 @@ where T: Copy + Clone +
}
/// Returns a transform with a rotation applied after self's transformation.
#[cfg_attr(feature = "unstable", must_use)]
#[must_use]
pub fn post_rotate(&self, x: T, y: T, z: T, theta: Angle<T>) -> Self {
self.post_mul(&TypedTransform3D::create_rotation(x, y, z, theta))
self.post_transform(&Transform3D::create_rotation(x, y, z, theta))
}
/// Returns a transform with a rotation applied before self's transformation.
#[cfg_attr(feature = "unstable", must_use)]
#[must_use]
pub fn pre_rotate(&self, x: T, y: T, z: T, theta: Angle<T>) -> Self {
self.pre_mul(&TypedTransform3D::create_rotation(x, y, z, theta))
self.pre_transform(&Transform3D::create_rotation(x, y, z, theta))
}
/// Create a 2d skew transform.
@ -668,7 +786,7 @@ where T: Copy + Clone +
pub fn create_skew(alpha: Angle<T>, beta: Angle<T>) -> Self {
let (_0, _1): (T, T) = (Zero::zero(), One::one());
let (sx, sy) = (beta.get().tan(), alpha.get().tan());
TypedTransform3D::row_major(
Transform3D::row_major(
_1, sx, _0, _0,
sy, _1, _0, _0,
_0, _0, _1, _0,
@ -679,7 +797,7 @@ where T: Copy + Clone +
/// Create a simple perspective projection transform
pub fn create_perspective(d: T) -> Self {
let (_0, _1): (T, T) = (Zero::zero(), One::one());
TypedTransform3D::row_major(
Transform3D::row_major(
_1, _0, _0, _0,
_0, _1, _0, _0,
_0, _0, _1, -_1 / d,
@ -688,7 +806,7 @@ where T: Copy + Clone +
}
}
impl<T: Copy, Src, Dst> TypedTransform3D<T, Src, Dst> {
impl<T: Copy, Src, Dst> Transform3D<T, Src, Dst> {
/// Returns an array containing this transform's terms in row-major order (the order
/// in which the transform is actually laid out in memory).
///
@ -781,14 +899,14 @@ impl<T: Copy, Src, Dst> TypedTransform3D<T, Src, Dst> {
}
}
impl<T0: NumCast + Copy, Src, Dst> TypedTransform3D<T0, Src, Dst> {
impl<T0: NumCast + Copy, Src, Dst> Transform3D<T0, Src, Dst> {
/// Cast from one numeric representation to another, preserving the units.
pub fn cast<T1: NumCast + Copy>(&self) -> TypedTransform3D<T1, Src, Dst> {
pub fn cast<T1: NumCast + Copy>(&self) -> Transform3D<T1, Src, Dst> {
self.try_cast().unwrap()
}
/// Fallible cast from one numeric representation to another, preserving the units.
pub fn try_cast<T1: NumCast + Copy>(&self) -> Option<TypedTransform3D<T1, Src, Dst>> {
pub fn try_cast<T1: NumCast + Copy>(&self) -> Option<Transform3D<T1, Src, Dst>> {
match (NumCast::from(self.m11), NumCast::from(self.m12),
NumCast::from(self.m13), NumCast::from(self.m14),
NumCast::from(self.m21), NumCast::from(self.m22),
@ -801,7 +919,7 @@ impl<T0: NumCast + Copy, Src, Dst> TypedTransform3D<T0, Src, Dst> {
Some(m21), Some(m22), Some(m23), Some(m24),
Some(m31), Some(m32), Some(m33), Some(m34),
Some(m41), Some(m42), Some(m43), Some(m44)) => {
Some(TypedTransform3D::row_major(m11, m12, m13, m14,
Some(Transform3D::row_major(m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44))
@ -811,7 +929,7 @@ impl<T0: NumCast + Copy, Src, Dst> TypedTransform3D<T0, Src, Dst> {
}
}
impl <T, Src, Dst> Default for TypedTransform3D<T, Src, Dst>
impl <T, Src, Dst> Default for Transform3D<T, Src, Dst>
where T: Copy + PartialEq + One + Zero
{
fn default() -> Self {
@ -819,7 +937,7 @@ impl <T, Src, Dst> Default for TypedTransform3D<T, Src, Dst>
}
}
impl<T, Src, Dst> fmt::Debug for TypedTransform3D<T, Src, Dst>
impl<T, Src, Dst> fmt::Debug for Transform3D<T, Src, Dst>
where T: Copy + fmt::Debug +
PartialEq +
One + Zero {
@ -833,9 +951,9 @@ where T: Copy + fmt::Debug +
}
#[cfg(feature = "mint")]
impl<T, Src, Dst> From<mint::RowMatrix4<T>> for TypedTransform3D<T, Src, Dst> {
impl<T, Src, Dst> From<mint::RowMatrix4<T>> for Transform3D<T, Src, Dst> {
fn from(m: mint::RowMatrix4<T>) -> Self {
TypedTransform3D {
Transform3D {
m11: m.x.x, m12: m.x.y, m13: m.x.z, m14: m.x.w,
m21: m.y.x, m22: m.y.y, m23: m.y.z, m24: m.y.w,
m31: m.z.x, m32: m.z.y, m33: m.z.z, m34: m.z.w,
@ -845,7 +963,7 @@ impl<T, Src, Dst> From<mint::RowMatrix4<T>> for TypedTransform3D<T, Src, Dst> {
}
}
#[cfg(feature = "mint")]
impl<T, Src, Dst> Into<mint::RowMatrix4<T>> for TypedTransform3D<T, Src, Dst> {
impl<T, Src, Dst> Into<mint::RowMatrix4<T>> for Transform3D<T, Src, Dst> {
fn into(self) -> mint::RowMatrix4<T> {
mint::RowMatrix4 {
x: mint::Vector4 { x: self.m11, y: self.m12, z: self.m13, w: self.m14 },
@ -860,14 +978,13 @@ impl<T, Src, Dst> Into<mint::RowMatrix4<T>> for TypedTransform3D<T, Src, Dst> {
#[cfg(test)]
mod tests {
use approxeq::ApproxEq;
use transform2d::Transform2D;
use point::{point2, point3};
use Angle;
use super::*;
use {point2, point3};
use default;
use core::f32::consts::{FRAC_PI_2, PI};
type Mf32 = Transform3D<f32>;
type Mf32 = default::Transform3D<f32>;
// For convenience.
fn rad(v: f32) -> Angle<f32> { Angle::radians(v) }
@ -880,10 +997,10 @@ mod tests {
assert_eq!(t1, t2);
assert_eq!(t1, t3);
assert_eq!(t1.transform_point3d(&point3(1.0, 1.0, 1.0)), Some(point3(2.0, 3.0, 4.0)));
assert_eq!(t1.transform_point2d(&point2(1.0, 1.0)), Some(point2(2.0, 3.0)));
assert_eq!(t1.transform_point3d(point3(1.0, 1.0, 1.0)), Some(point3(2.0, 3.0, 4.0)));
assert_eq!(t1.transform_point2d(point2(1.0, 1.0)), Some(point2(2.0, 3.0)));
assert_eq!(t1.post_mul(&t1), Mf32::create_translation(2.0, 4.0, 6.0));
assert_eq!(t1.post_transform(&t1), Mf32::create_translation(2.0, 4.0, 6.0));
assert!(!t1.is_2d());
assert_eq!(Mf32::create_translation(1.0, 2.0, 3.0).to_2d(), Transform2D::create_translation(1.0, 2.0));
@ -897,10 +1014,10 @@ mod tests {
assert_eq!(r1, r2);
assert_eq!(r1, r3);
assert!(r1.transform_point3d(&point3(1.0, 2.0, 3.0)).unwrap().approx_eq(&point3(2.0, -1.0, 3.0)));
assert!(r1.transform_point2d(&point2(1.0, 2.0)).unwrap().approx_eq(&point2(2.0, -1.0)));
assert!(r1.transform_point3d(point3(1.0, 2.0, 3.0)).unwrap().approx_eq(&point3(2.0, -1.0, 3.0)));
assert!(r1.transform_point2d(point2(1.0, 2.0)).unwrap().approx_eq(&point2(2.0, -1.0)));
assert!(r1.post_mul(&r1).approx_eq(&Mf32::create_rotation(0.0, 0.0, 1.0, rad(FRAC_PI_2*2.0))));
assert!(r1.post_transform(&r1).approx_eq(&Mf32::create_rotation(0.0, 0.0, 1.0, rad(FRAC_PI_2*2.0))));
assert!(r1.is_2d());
assert!(r1.to_2d().approx_eq(&Transform2D::create_rotation(rad(FRAC_PI_2))));
@ -914,10 +1031,10 @@ mod tests {
assert_eq!(s1, s2);
assert_eq!(s1, s3);
assert!(s1.transform_point3d(&point3(2.0, 2.0, 2.0)).unwrap().approx_eq(&point3(4.0, 6.0, 8.0)));
assert!(s1.transform_point2d(&point2(2.0, 2.0)).unwrap().approx_eq(&point2(4.0, 6.0)));
assert!(s1.transform_point3d(point3(2.0, 2.0, 2.0)).unwrap().approx_eq(&point3(4.0, 6.0, 8.0)));
assert!(s1.transform_point2d(point2(2.0, 2.0)).unwrap().approx_eq(&point2(4.0, 6.0)));
assert_eq!(s1.post_mul(&s1), Mf32::create_scale(4.0, 9.0, 16.0));
assert_eq!(s1.post_transform(&s1), Mf32::create_scale(4.0, 9.0, 16.0));
assert!(!s1.is_2d());
assert_eq!(Mf32::create_scale(2.0, 3.0, 0.0).to_2d(), Transform2D::create_scale(2.0, 3.0));
@ -985,34 +1102,34 @@ mod tests {
pub fn test_inverse_scale() {
let m1 = Mf32::create_scale(1.5, 0.3, 2.1);
let m2 = m1.inverse().unwrap();
assert!(m1.pre_mul(&m2).approx_eq(&Mf32::identity()));
assert!(m1.pre_transform(&m2).approx_eq(&Mf32::identity()));
}
#[test]
pub fn test_inverse_translate() {
let m1 = Mf32::create_translation(-132.0, 0.3, 493.0);
let m2 = m1.inverse().unwrap();
assert!(m1.pre_mul(&m2).approx_eq(&Mf32::identity()));
assert!(m1.pre_transform(&m2).approx_eq(&Mf32::identity()));
}
#[test]
pub fn test_inverse_rotate() {
let m1 = Mf32::create_rotation(0.0, 1.0, 0.0, rad(1.57));
let m2 = m1.inverse().unwrap();
assert!(m1.pre_mul(&m2).approx_eq(&Mf32::identity()));
assert!(m1.pre_transform(&m2).approx_eq(&Mf32::identity()));
}
#[test]
pub fn test_inverse_transform_point_2d() {
let m1 = Mf32::create_translation(100.0, 200.0, 0.0);
let m2 = m1.inverse().unwrap();
assert!(m1.pre_mul(&m2).approx_eq(&Mf32::identity()));
assert!(m1.pre_transform(&m2).approx_eq(&Mf32::identity()));
let p1 = point2(1000.0, 2000.0);
let p2 = m1.transform_point2d(&p1);
let p2 = m1.transform_point2d(p1);
assert_eq!(p2, Some(point2(1100.0, 2200.0)));
let p3 = m2.transform_point2d(&p2.unwrap());
let p3 = m2.transform_point2d(p2.unwrap());
assert_eq!(p3, Some(p1));
}
@ -1024,8 +1141,8 @@ mod tests {
#[test]
pub fn test_pre_post() {
let m1 = Transform3D::identity().post_scale(1.0, 2.0, 3.0).post_translate(vec3(1.0, 2.0, 3.0));
let m2 = Transform3D::identity().pre_translate(vec3(1.0, 2.0, 3.0)).pre_scale(1.0, 2.0, 3.0);
let m1 = default::Transform3D::identity().post_scale(1.0, 2.0, 3.0).post_translate(vec3(1.0, 2.0, 3.0));
let m2 = default::Transform3D::identity().pre_translate(vec3(1.0, 2.0, 3.0)).pre_scale(1.0, 2.0, 3.0);
assert!(m1.approx_eq(&m2));
let r = Mf32::create_rotation(0.0, 0.0, 1.0, rad(FRAC_PI_2));
@ -1033,20 +1150,20 @@ mod tests {
let a = point3(1.0, 1.0, 1.0);
assert!(r.post_mul(&t).transform_point3d(&a).unwrap().approx_eq(&point3(3.0, 2.0, 1.0)));
assert!(t.post_mul(&r).transform_point3d(&a).unwrap().approx_eq(&point3(4.0, -3.0, 1.0)));
assert!(t.post_mul(&r).transform_point3d(&a).unwrap().approx_eq(&r.transform_point3d(&t.transform_point3d(&a).unwrap()).unwrap()));
assert!(r.post_transform(&t).transform_point3d(a).unwrap().approx_eq(&point3(3.0, 2.0, 1.0)));
assert!(t.post_transform(&r).transform_point3d(a).unwrap().approx_eq(&point3(4.0, -3.0, 1.0)));
assert!(t.post_transform(&r).transform_point3d(a).unwrap().approx_eq(&r.transform_point3d(t.transform_point3d(a).unwrap()).unwrap()));
assert!(r.pre_mul(&t).transform_point3d(&a).unwrap().approx_eq(&point3(4.0, -3.0, 1.0)));
assert!(t.pre_mul(&r).transform_point3d(&a).unwrap().approx_eq(&point3(3.0, 2.0, 1.0)));
assert!(t.pre_mul(&r).transform_point3d(&a).unwrap().approx_eq(&t.transform_point3d(&r.transform_point3d(&a).unwrap()).unwrap()));
assert!(r.pre_transform(&t).transform_point3d(a).unwrap().approx_eq(&point3(4.0, -3.0, 1.0)));
assert!(t.pre_transform(&r).transform_point3d(a).unwrap().approx_eq(&point3(3.0, 2.0, 1.0)));
assert!(t.pre_transform(&r).transform_point3d(a).unwrap().approx_eq(&t.transform_point3d(r.transform_point3d(a).unwrap()).unwrap()));
}
#[test]
fn test_size_of() {
use core::mem::size_of;
assert_eq!(size_of::<Transform3D<f32>>(), 16*size_of::<f32>());
assert_eq!(size_of::<Transform3D<f64>>(), 16*size_of::<f64>());
assert_eq!(size_of::<default::Transform3D<f32>>(), 16*size_of::<f32>());
assert_eq!(size_of::<default::Transform3D<f64>>(), 16*size_of::<f64>());
}
#[test]
@ -1061,14 +1178,14 @@ mod tests {
-2.5, 6.0, 1.0, 1.0);
let p = point3(1.0, 3.0, 5.0);
let p1 = m2.pre_mul(&m1).transform_point3d(&p).unwrap();
let p2 = m2.transform_point3d(&m1.transform_point3d(&p).unwrap()).unwrap();
let p1 = m2.pre_transform(&m1).transform_point3d(p).unwrap();
let p2 = m2.transform_point3d(m1.transform_point3d(p).unwrap()).unwrap();
assert!(p1.approx_eq(&p2));
}
#[test]
pub fn test_is_identity() {
let m1 = Transform3D::identity();
let m1 = default::Transform3D::identity();
assert!(m1.is_identity());
let m2 = m1.post_translate(vec3(0.1, 0.0, 0.0));
assert!(!m2.is_identity());
@ -1079,14 +1196,14 @@ mod tests {
// Translation does not apply to vectors.
let m = Mf32::create_translation(1.0, 2.0, 3.0);
let v1 = vec3(10.0, -10.0, 3.0);
assert_eq!(v1, m.transform_vector3d(&v1));
assert_eq!(v1, m.transform_vector3d(v1));
// While it does apply to points.
assert_ne!(Some(v1.to_point()), m.transform_point3d(&v1.to_point()));
assert_ne!(Some(v1.to_point()), m.transform_point3d(v1.to_point()));
// same thing with 2d vectors/points
let v2 = vec2(10.0, -5.0);
assert_eq!(v2, m.transform_vector2d(&v2));
assert_ne!(Some(v2.to_point()), m.transform_point2d(&v2.to_point()));
assert_eq!(v2, m.transform_vector2d(v2));
assert_ne!(Some(v2.to_point()), m.transform_point2d(v2.to_point()));
}
#[test]
@ -1117,11 +1234,11 @@ mod tests {
-1.0, 1.0, -1.0, 2.0,
);
assert_eq!(
m.transform_point2d_homogeneous(&point2(1.0, 2.0)),
m.transform_point2d_homogeneous(point2(1.0, 2.0)),
HomogeneousVector::new(6.0, 11.0, 0.0, 19.0),
);
assert_eq!(
m.transform_point3d_homogeneous(&point3(1.0, 2.0, 4.0)),
m.transform_point3d_homogeneous(point3(1.0, 2.0, 4.0)),
HomogeneousVector::new(8.0, 7.0, 4.0, 15.0),
);
}
@ -1130,12 +1247,12 @@ mod tests {
pub fn test_perspective_division() {
let p = point2(1.0, 2.0);
let mut m = Mf32::identity();
assert!(m.transform_point2d(&p).is_some());
assert!(m.transform_point2d(p).is_some());
m.m44 = 0.0;
assert_eq!(None, m.transform_point2d(&p));
assert_eq!(None, m.transform_point2d(p));
m.m44 = 1.0;
m.m24 = -1.0;
assert_eq!(None, m.transform_point2d(&p));
assert_eq!(None, m.transform_point2d(p));
}
#[cfg(feature = "mint")]

289
third_party/rust/euclid/src/translation.rs поставляемый
Просмотреть файл

@ -7,47 +7,83 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use {TypedVector2D, TypedPoint2D, TypedVector3D, TypedPoint3D, TypedTransform2D, TypedTransform3D};
use {TypedSize2D, TypedRect, vec2, point2, vec3, point3};
use {Vector2D, Point2D, Vector3D, Point3D, Transform2D, Transform3D};
use {Size2D, Rect, vec2, point2, vec3, point3};
use num::*;
use trig::Trig;
use core::ops::{Add, Sub, Neg, Mul, Div};
use core::marker::PhantomData;
use core::fmt;
use core::cmp::{Eq, PartialEq};
use core::hash::{Hash};
#[cfg(feature = "serde")]
use serde;
/// A 2d transformation from a space to another that can only express translations.
///
/// The main benefit of this type over a TypedVector2D is the ability to cast
/// The main benefit of this type over a Vector2D is the ability to cast
/// between a source and a destination spaces.
///
/// Example:
///
/// ```
/// use euclid::{TypedTranslation2D, TypedPoint2D, point2};
/// use euclid::{Translation2D, Point2D, point2};
/// struct ParentSpace;
/// struct ChildSpace;
/// type ScrollOffset = TypedTranslation2D<i32, ParentSpace, ChildSpace>;
/// type ParentPoint = TypedPoint2D<i32, ParentSpace>;
/// type ChildPoint = TypedPoint2D<i32, ChildSpace>;
/// type ScrollOffset = Translation2D<i32, ParentSpace, ChildSpace>;
/// type ParentPoint = Point2D<i32, ParentSpace>;
/// type ChildPoint = Point2D<i32, ChildSpace>;
///
/// let scrolling = ScrollOffset::new(0, 100);
/// let p1: ParentPoint = point2(0, 0);
/// let p2: ChildPoint = scrolling.transform_point(&p1);
/// let p2: ChildPoint = scrolling.transform_point(p1);
/// ```
///
#[derive(EuclidMatrix)]
#[repr(C)]
pub struct TypedTranslation2D<T, Src, Dst> {
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(bound(serialize = "T: serde::Serialize", deserialize = "T: serde::Deserialize<'de>")))]
pub struct Translation2D<T, Src, Dst> {
pub x: T,
pub y: T,
#[doc(hidden)]
pub _unit: PhantomData<(Src, Dst)>,
}
impl<T, Src, Dst> TypedTranslation2D<T, Src, Dst> {
impl<T: Copy, Src, Dst> Copy for Translation2D<T, Src, Dst> {}
impl<T: Clone, Src, Dst> Clone for Translation2D<T, Src, Dst> {
fn clone(&self) -> Self {
Translation2D {
x: self.x.clone(),
y: self.y.clone(),
_unit: PhantomData,
}
}
}
impl<T, Src, Dst> Eq for Translation2D<T, Src, Dst> where T: Eq {}
impl<T, Src, Dst> PartialEq for Translation2D<T, Src, Dst>
where T: PartialEq
{
fn eq(&self, other: &Self) -> bool {
self.x == other.x && self.y == other.y
}
}
impl<T, Src, Dst> Hash for Translation2D<T, Src, Dst>
where T: Hash
{
fn hash<H: ::core::hash::Hasher>(&self, h: &mut H) {
self.x.hash(h);
self.y.hash(h);
}
}
impl<T, Src, Dst> Translation2D<T, Src, Dst> {
#[inline]
pub fn new(x: T, y: T) -> Self {
TypedTranslation2D {
Translation2D {
x,
y,
_unit: PhantomData,
@ -55,7 +91,7 @@ impl<T, Src, Dst> TypedTranslation2D<T, Src, Dst> {
}
}
impl<T, Src, Dst> TypedTranslation2D<T, Src, Dst>
impl<T, Src, Dst> Translation2D<T, Src, Dst>
where
T : Copy
{
@ -70,18 +106,18 @@ where
}
}
impl<T, Src, Dst> TypedTranslation2D<T, Src, Dst>
impl<T, Src, Dst> Translation2D<T, Src, Dst>
where
T : Copy + Zero
{
#[inline]
pub fn identity() -> Self {
let _0 = T::zero();
TypedTranslation2D::new(_0, _0)
Translation2D::new(_0, _0)
}
}
impl<T, Src, Dst> TypedTranslation2D<T, Src, Dst>
impl<T, Src, Dst> Translation2D<T, Src, Dst>
where
T: Zero + PartialEq
{
@ -91,56 +127,56 @@ where
}
}
impl<T, Src, Dst> TypedTranslation2D<T, Src, Dst>
impl<T, Src, Dst> Translation2D<T, Src, Dst>
where
T: Copy + Add<T, Output = T>
{
/// Translate a point and cast its unit.
#[inline]
pub fn transform_point(&self, p: &TypedPoint2D<T, Src>) -> TypedPoint2D<T, Dst> {
pub fn transform_point(&self, p: Point2D<T, Src>) -> Point2D<T, Dst> {
point2(p.x + self.x, p.y + self.y)
}
/// Translate a rectangle and cast its unit.
#[inline]
pub fn transform_rect(&self, r: &TypedRect<T, Src>) -> TypedRect<T, Dst> {
TypedRect {
origin: self.transform_point(&r.origin),
size: self.transform_size(&r.size),
pub fn transform_rect(&self, r: &Rect<T, Src>) -> Rect<T, Dst> {
Rect {
origin: self.transform_point(r.origin),
size: self.transform_size(r.size),
}
}
/// No-op, just cast the unit.
#[inline]
pub fn transform_size(&self, s: &TypedSize2D<T, Src>) -> TypedSize2D<T, Dst> {
TypedSize2D::new(s.width, s.height)
pub fn transform_size(&self, s: Size2D<T, Src>) -> Size2D<T, Dst> {
Size2D::new(s.width, s.height)
}
/// Cast into a 2D vector.
pub fn to_vector(&self) -> TypedVector2D<T, Src> {
pub fn to_vector(&self) -> Vector2D<T, Src> {
vec2(self.x, self.y)
}
}
impl<T, Src, Dst> TypedTranslation2D<T, Src, Dst>
impl<T, Src, Dst> Translation2D<T, Src, Dst>
where
T: Copy + Neg<Output = T>
{
/// Return the inverse transformation.
#[inline]
pub fn inverse(&self) -> TypedTranslation2D<T, Dst, Src> {
TypedTranslation2D::new(-self.x, -self.y)
pub fn inverse(&self) -> Translation2D<T, Dst, Src> {
Translation2D::new(-self.x, -self.y)
}
}
impl<T, Src, Dst1, Dst2> Add<TypedTranslation2D<T, Dst1, Dst2>>
for TypedTranslation2D<T, Src, Dst1>
impl<T, Src, Dst1, Dst2> Add<Translation2D<T, Dst1, Dst2>>
for Translation2D<T, Src, Dst1>
where
T: Copy + Add<T, Output = T>
{
type Output = TypedTranslation2D<T, Src, Dst2>;
fn add(self, other: TypedTranslation2D<T, Dst1, Dst2>) -> TypedTranslation2D<T, Src, Dst2> {
TypedTranslation2D::new(
type Output = Translation2D<T, Src, Dst2>;
fn add(self, other: Translation2D<T, Dst1, Dst2>) -> Translation2D<T, Src, Dst2> {
Translation2D::new(
self.x + other.x,
self.y + other.y,
)
@ -148,21 +184,21 @@ where
}
impl<T, Src, Dst1, Dst2>
Sub<TypedTranslation2D<T, Dst1, Dst2>>
for TypedTranslation2D<T, Src, Dst2>
Sub<Translation2D<T, Dst1, Dst2>>
for Translation2D<T, Src, Dst2>
where
T: Copy + Sub<T, Output = T>
{
type Output = TypedTranslation2D<T, Src, Dst1>;
fn sub(self, other: TypedTranslation2D<T, Dst1, Dst2>) -> TypedTranslation2D<T, Src, Dst1> {
TypedTranslation2D::new(
type Output = Translation2D<T, Src, Dst1>;
fn sub(self, other: Translation2D<T, Dst1, Dst2>) -> Translation2D<T, Src, Dst1> {
Translation2D::new(
self.x - other.x,
self.y - other.y,
)
}
}
impl<T, Src, Dst> TypedTranslation2D<T, Src, Dst>
impl<T, Src, Dst> Translation2D<T, Src, Dst>
where
T: Copy
+ Clone
@ -177,30 +213,30 @@ where
{
/// Returns the matrix representation of this translation.
#[inline]
pub fn to_transform(&self) -> TypedTransform2D<T, Src, Dst> {
TypedTransform2D::create_translation(self.x, self.y)
pub fn to_transform(&self) -> Transform2D<T, Src, Dst> {
Transform2D::create_translation(self.x, self.y)
}
}
impl<T, Src, Dst> From<TypedVector2D<T, Src>> for TypedTranslation2D<T, Src, Dst>
impl<T, Src, Dst> From<Vector2D<T, Src>> for Translation2D<T, Src, Dst>
where
T: Copy
{
fn from(v: TypedVector2D<T, Src>) -> Self {
TypedTranslation2D::new(v.x, v.y)
fn from(v: Vector2D<T, Src>) -> Self {
Translation2D::new(v.x, v.y)
}
}
impl<T, Src, Dst> Into<TypedVector2D<T, Src>> for TypedTranslation2D<T, Src, Dst>
impl<T, Src, Dst> Into<Vector2D<T, Src>> for Translation2D<T, Src, Dst>
where
T: Copy
{
fn into(self) -> TypedVector2D<T, Src> {
fn into(self) -> Vector2D<T, Src> {
vec2(self.x, self.y)
}
}
impl<T, Src, Dst> Into<TypedTransform2D<T, Src, Dst>> for TypedTranslation2D<T, Src, Dst>
impl<T, Src, Dst> Into<Transform2D<T, Src, Dst>> for Translation2D<T, Src, Dst>
where
T: Copy
+ Clone
@ -213,12 +249,12 @@ where
+ One
+ Zero,
{
fn into(self) -> TypedTransform2D<T, Src, Dst> {
fn into(self) -> Transform2D<T, Src, Dst> {
self.to_transform()
}
}
impl <T, Src, Dst> Default for TypedTranslation2D<T, Src, Dst>
impl <T, Src, Dst> Default for Translation2D<T, Src, Dst>
where T: Copy + Zero
{
fn default() -> Self {
@ -226,7 +262,7 @@ impl <T, Src, Dst> Default for TypedTranslation2D<T, Src, Dst>
}
}
impl<T, Src, Dst> fmt::Debug for TypedTranslation2D<T, Src, Dst>
impl<T, Src, Dst> fmt::Debug for Translation2D<T, Src, Dst>
where T: Copy + fmt::Debug {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.to_array().fmt(f)
@ -237,11 +273,10 @@ where T: Copy + fmt::Debug {
/// A 3d transformation from a space to another that can only express translations.
///
/// The main benefit of this type over a TypedVector3D is the ability to cast
/// The main benefit of this type over a Vector3D is the ability to cast
/// between a source and a destination spaces.
#[derive(EuclidMatrix)]
#[repr(C)]
pub struct TypedTranslation3D<T, Src, Dst> {
pub struct Translation3D<T, Src, Dst> {
pub x: T,
pub y: T,
pub z: T,
@ -249,10 +284,66 @@ pub struct TypedTranslation3D<T, Src, Dst> {
pub _unit: PhantomData<(Src, Dst)>,
}
impl<T, Src, Dst> TypedTranslation3D<T, Src, Dst> {
impl<T: Copy, Src, Dst> Copy for Translation3D<T, Src, Dst> {}
impl<T: Clone, Src, Dst> Clone for Translation3D<T, Src, Dst> {
fn clone(&self) -> Self {
Translation3D {
x: self.x.clone(),
y: self.y.clone(),
z: self.z.clone(),
_unit: PhantomData,
}
}
}
#[cfg(feature = "serde")]
impl<'de, T, Src, Dst> serde::Deserialize<'de> for Translation3D<T, Src, Dst>
where T: serde::Deserialize<'de>
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: serde::Deserializer<'de>
{
let (x, y, z) = try!(serde::Deserialize::deserialize(deserializer));
Ok(Translation3D { x, y, z, _unit: PhantomData })
}
}
#[cfg(feature = "serde")]
impl<T, Src, Dst> serde::Serialize for Translation3D<T, Src, Dst>
where T: serde::Serialize
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: serde::Serializer
{
(&self.x, &self.y, &self.z).serialize(serializer)
}
}
impl<T, Src, Dst> Eq for Translation3D<T, Src, Dst> where T: Eq {}
impl<T, Src, Dst> PartialEq for Translation3D<T, Src, Dst>
where T: PartialEq
{
fn eq(&self, other: &Self) -> bool {
self.x == other.x && self.y == other.y && self.z == other.z
}
}
impl<T, Src, Dst> Hash for Translation3D<T, Src, Dst>
where T: Hash
{
fn hash<H: ::core::hash::Hasher>(&self, h: &mut H) {
self.x.hash(h);
self.y.hash(h);
self.z.hash(h);
}
}
impl<T, Src, Dst> Translation3D<T, Src, Dst> {
#[inline]
pub fn new(x: T, y: T, z: T) -> Self {
TypedTranslation3D {
Translation3D {
x,
y,
z,
@ -261,7 +352,7 @@ impl<T, Src, Dst> TypedTranslation3D<T, Src, Dst> {
}
}
impl<T, Src, Dst> TypedTranslation3D<T, Src, Dst>
impl<T, Src, Dst> Translation3D<T, Src, Dst>
where
T: Copy
{
@ -276,18 +367,18 @@ where
}
}
impl<T, Src, Dst> TypedTranslation3D<T, Src, Dst>
impl<T, Src, Dst> Translation3D<T, Src, Dst>
where
T: Copy + Zero
{
#[inline]
pub fn identity() -> Self {
let _0 = T::zero();
TypedTranslation3D::new(_0, _0, _0)
Translation3D::new(_0, _0, _0)
}
}
impl<T, Src, Dst> TypedTranslation3D<T, Src, Dst>
impl<T, Src, Dst> Translation3D<T, Src, Dst>
where
T: Zero + PartialEq
{
@ -297,62 +388,62 @@ where
}
}
impl<T, Src, Dst> TypedTranslation3D<T, Src, Dst>
impl<T, Src, Dst> Translation3D<T, Src, Dst>
where
T: Copy + Add<T, Output = T>
{
/// Translate a point and cast its unit.
#[inline]
pub fn transform_point3d(&self, p: &TypedPoint3D<T, Src>) -> TypedPoint3D<T, Dst> {
pub fn transform_point3d(&self, p: &Point3D<T, Src>) -> Point3D<T, Dst> {
point3(p.x + self.x, p.y + self.y, p.z + self.z)
}
/// Translate a point and cast its unit.
#[inline]
pub fn transform_point2d(&self, p: &TypedPoint2D<T, Src>) -> TypedPoint2D<T, Dst> {
pub fn transform_point2d(&self, p: &Point2D<T, Src>) -> Point2D<T, Dst> {
point2(p.x + self.x, p.y + self.y)
}
/// Translate a rectangle and cast its unit.
#[inline]
pub fn transform_rect(&self, r: &TypedRect<T, Src>) -> TypedRect<T, Dst> {
TypedRect {
pub fn transform_rect(&self, r: &Rect<T, Src>) -> Rect<T, Dst> {
Rect {
origin: self.transform_point2d(&r.origin),
size: self.transform_size(&r.size),
size: self.transform_size(r.size),
}
}
/// No-op, just cast the unit.
#[inline]
pub fn transform_size(&self, s: &TypedSize2D<T, Src>) -> TypedSize2D<T, Dst> {
TypedSize2D::new(s.width, s.height)
pub fn transform_size(self, s: Size2D<T, Src>) -> Size2D<T, Dst> {
Size2D::new(s.width, s.height)
}
/// Cast into a 3D vector.
pub fn to_vector(&self) -> TypedVector3D<T, Src> {
pub fn to_vector(&self) -> Vector3D<T, Src> {
vec3(self.x, self.y, self.z)
}
}
impl<T, Src, Dst> TypedTranslation3D<T, Src, Dst>
impl<T, Src, Dst> Translation3D<T, Src, Dst>
where
T: Copy + Neg<Output = T>
{
/// Return the inverse transformation.
#[inline]
pub fn inverse(&self) -> TypedTranslation3D<T, Dst, Src> {
TypedTranslation3D::new(-self.x, -self.y, -self.z)
pub fn inverse(&self) -> Translation3D<T, Dst, Src> {
Translation3D::new(-self.x, -self.y, -self.z)
}
}
impl<T, Src, Dst1, Dst2> Add<TypedTranslation3D<T, Dst1, Dst2>>
for TypedTranslation3D<T, Src, Dst1>
impl<T, Src, Dst1, Dst2> Add<Translation3D<T, Dst1, Dst2>>
for Translation3D<T, Src, Dst1>
where
T: Copy + Add<T, Output = T>
{
type Output = TypedTranslation3D<T, Src, Dst2>;
fn add(self, other: TypedTranslation3D<T, Dst1, Dst2>) -> TypedTranslation3D<T, Src, Dst2> {
TypedTranslation3D::new(
type Output = Translation3D<T, Src, Dst2>;
fn add(self, other: Translation3D<T, Dst1, Dst2>) -> Translation3D<T, Src, Dst2> {
Translation3D::new(
self.x + other.x,
self.y + other.y,
self.z + other.z,
@ -361,14 +452,14 @@ where
}
impl<T, Src, Dst1, Dst2>
Sub<TypedTranslation3D<T, Dst1, Dst2>>
for TypedTranslation3D<T, Src, Dst2>
Sub<Translation3D<T, Dst1, Dst2>>
for Translation3D<T, Src, Dst2>
where
T: Copy + Sub<T, Output = T>
{
type Output = TypedTranslation3D<T, Src, Dst1>;
fn sub(self, other: TypedTranslation3D<T, Dst1, Dst2>) -> TypedTranslation3D<T, Src, Dst1> {
TypedTranslation3D::new(
type Output = Translation3D<T, Src, Dst1>;
fn sub(self, other: Translation3D<T, Dst1, Dst2>) -> Translation3D<T, Src, Dst1> {
Translation3D::new(
self.x - other.x,
self.y - other.y,
self.z - other.z,
@ -376,7 +467,7 @@ where
}
}
impl<T, Src, Dst> TypedTranslation3D<T, Src, Dst>
impl<T, Src, Dst> Translation3D<T, Src, Dst>
where
T: Copy + Clone +
Add<T, Output=T> +
@ -390,30 +481,30 @@ where
{
/// Returns the matrix representation of this translation.
#[inline]
pub fn to_transform(&self) -> TypedTransform3D<T, Src, Dst> {
TypedTransform3D::create_translation(self.x, self.y, self.z)
pub fn to_transform(&self) -> Transform3D<T, Src, Dst> {
Transform3D::create_translation(self.x, self.y, self.z)
}
}
impl<T, Src, Dst> From<TypedVector3D<T, Src>> for TypedTranslation3D<T, Src, Dst>
impl<T, Src, Dst> From<Vector3D<T, Src>> for Translation3D<T, Src, Dst>
where
T: Copy
{
fn from(v: TypedVector3D<T, Src>) -> Self {
TypedTranslation3D::new(v.x, v.y, v.z)
fn from(v: Vector3D<T, Src>) -> Self {
Translation3D::new(v.x, v.y, v.z)
}
}
impl<T, Src, Dst> Into<TypedVector3D<T, Src>> for TypedTranslation3D<T, Src, Dst>
impl<T, Src, Dst> Into<Vector3D<T, Src>> for Translation3D<T, Src, Dst>
where
T: Copy
{
fn into(self) -> TypedVector3D<T, Src> {
fn into(self) -> Vector3D<T, Src> {
vec3(self.x, self.y, self.z)
}
}
impl<T, Src, Dst> Into<TypedTransform3D<T, Src, Dst>> for TypedTranslation3D<T, Src, Dst>
impl<T, Src, Dst> Into<Transform3D<T, Src, Dst>> for Translation3D<T, Src, Dst>
where
T: Copy + Clone +
Add<T, Output=T> +
@ -425,12 +516,12 @@ where
Trig +
One + Zero,
{
fn into(self) -> TypedTransform3D<T, Src, Dst> {
fn into(self) -> Transform3D<T, Src, Dst> {
self.to_transform()
}
}
impl <T, Src, Dst> Default for TypedTranslation3D<T, Src, Dst>
impl <T, Src, Dst> Default for Translation3D<T, Src, Dst>
where T: Copy + Zero
{
fn default() -> Self {
@ -438,7 +529,7 @@ impl <T, Src, Dst> Default for TypedTranslation3D<T, Src, Dst>
}
}
impl<T, Src, Dst> fmt::Debug for TypedTranslation3D<T, Src, Dst>
impl<T, Src, Dst> fmt::Debug for Translation3D<T, Src, Dst>
where T: Copy + fmt::Debug {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.to_array().fmt(f)
@ -452,9 +543,9 @@ fn simple_translation2d() {
struct A;
struct B;
type Translation = TypedTranslation2D<i32, A, B>;
type SrcRect = TypedRect<i32, A>;
type DstRect = TypedRect<i32, B>;
type Translation = Translation2D<i32, A, B>;
type SrcRect = Rect<i32, A>;
type DstRect = Rect<i32, B>;
let tx = Translation::new(10, -10);
let r1: SrcRect = rect(10, 20, 30, 40);
@ -472,9 +563,9 @@ fn simple_translation3d() {
struct A;
struct B;
type Translation = TypedTranslation3D<i32, A, B>;
type SrcPoint = TypedPoint3D<i32, A>;
type DstPoint = TypedPoint3D<i32, B>;
type Translation = Translation3D<i32, A, B>;
type SrcPoint = Point3D<i32, A>;
type DstPoint = Point3D<i32, B>;
let tx = Translation::new(10, -10, 100);
let p1: SrcPoint = point3(10, 20, 30);

555
third_party/rust/euclid/src/vector.rs поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1 +0,0 @@
{"files":{"Cargo.toml":"12f4357876f09242153fbbd912c70861b03d5a8f983fce3de0d3696389452be6","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"62065228e42caebca7e7d7db1204cbb867033de5982ca4009928915e4095f3a3","euclid_matrix.rs":"0643b38d8284278c3d54a3791aa0eae7edd5f73a54e1edec38e1bcdb4af66e0b","lib.rs":"845b9a82365e06d51edce03560a5abe617f955c9c640e90140c87fb594c65fbd"},"package":"fdcb84c18ea5037a1c5a23039b4ff29403abce2e0d6b1daa11cf0bde2b30be15"}

31
third_party/rust/euclid_macros/Cargo.toml поставляемый
Просмотреть файл

@ -1,31 +0,0 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g. crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package]
name = "euclid_macros"
version = "0.1.0"
authors = ["Emilio Cobos Álvarez <emilio@crisal.io>", "The Servo project developers"]
description = "Euclid implementation detail"
license = "MIT / Apache-2.0"
[lib]
path = "lib.rs"
proc-macro = true
[dependencies.proc-macro2]
version = "0.4"
[dependencies.quote]
version = "0.6"
[dependencies.syn]
version = "0.15"
features = ["visit"]

201
third_party/rust/euclid_macros/LICENSE-APACHE поставляемый
Просмотреть файл

@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

25
third_party/rust/euclid_macros/LICENSE-MIT поставляемый
Просмотреть файл

@ -1,25 +0,0 @@
Copyright (c) 2012-2013 Mozilla Foundation
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

Просмотреть файл

@ -1,247 +0,0 @@
use proc_macro2::TokenStream;
use syn::{self, DeriveInput};
type Fields = syn::punctuated::Punctuated<syn::Field, syn::token::Comma>;
fn derive_trait<F>(
input: &DeriveInput,
trait_name: TokenStream,
generics: &syn::Generics,
body: F
) -> TokenStream
where
F: FnOnce() -> TokenStream,
{
let struct_name = &input.ident;
let (impl_generics, _, where_clause) = generics.split_for_impl();
let (_, ty_generics, _) = input.generics.split_for_impl();
let body = body();
quote! {
impl #impl_generics #trait_name for #struct_name #ty_generics #where_clause {
#body
}
}
}
fn derive_simple_trait<F>(
input: &DeriveInput,
trait_name: TokenStream,
t: &syn::TypeParam,
body: F,
) -> TokenStream
where
F: FnOnce() -> TokenStream,
{
let mut generics = input.generics.clone();
generics
.make_where_clause()
.predicates
.push(parse_quote!(#t: #trait_name));
derive_trait(input, trait_name, &generics, body)
}
fn each_field_except_unit<F>(
fields: &Fields,
unit: &syn::Field,
mut field_expr: F,
) -> TokenStream
where
F: FnMut(&syn::Ident) -> TokenStream,
{
fields.iter().filter(|f| f.ident != unit.ident).fold(quote! {}, |body, field| {
let name = field.ident.as_ref().unwrap();
let expr = field_expr(name);
quote! {
#body
#expr
}
})
}
fn derive_struct_body<F>(
fields: &Fields,
unit: &syn::Field,
mut field_expr: F,
) -> TokenStream
where
F: FnMut(&syn::Ident) -> TokenStream,
{
let body = each_field_except_unit(fields, unit, |name| {
let expr = field_expr(name);
quote! {
#name: #expr,
}
});
let unit_name = unit.ident.as_ref().unwrap();
quote! {
Self {
#body
#unit_name: PhantomData,
}
}
}
fn clone_impl(input: &DeriveInput, fields: &Fields, unit: &syn::Field, t: &syn::TypeParam) -> TokenStream {
derive_simple_trait(input, quote! { Clone }, t, || {
let body = derive_struct_body(fields, unit, |name| {
quote! { self.#name.clone() }
});
quote! {
fn clone(&self) -> Self {
#body
}
}
})
}
fn copy_impl(input: &DeriveInput, t: &syn::TypeParam) -> TokenStream {
derive_simple_trait(input, quote!{ Copy }, t, || quote! {})
}
fn eq_impl(input: &DeriveInput, t: &syn::TypeParam) -> TokenStream {
derive_simple_trait(input, quote!{ ::core::cmp::Eq }, t, || quote! {})
}
fn partialeq_impl(input: &DeriveInput, fields: &Fields, unit: &syn::Field, t: &syn::TypeParam) -> TokenStream {
derive_simple_trait(input, quote!{ ::core::cmp::PartialEq }, t, || {
let body = each_field_except_unit(fields, unit, |name| {
quote! { && self.#name == other.#name }
});
quote! {
fn eq(&self, other: &Self) -> bool {
true #body
}
}
})
}
fn hash_impl(input: &DeriveInput, fields: &Fields, unit: &syn::Field, t: &syn::TypeParam) -> TokenStream {
derive_simple_trait(input, quote!{ ::core::hash::Hash }, t, || {
let body = each_field_except_unit(fields, unit, |name| {
quote! { self.#name.hash(h); }
});
quote! {
fn hash<H: ::core::hash::Hasher>(&self, h: &mut H) {
#body
}
}
})
}
fn serde_impl(
input: &DeriveInput,
fields: &Fields,
unit: &syn::Field,
t: &syn::TypeParam,
) -> TokenStream {
let deserialize_impl = {
let mut generics = input.generics.clone();
generics.params.insert(0, parse_quote!('de));
generics
.make_where_clause()
.predicates
.push(parse_quote!(#t: ::serde::Deserialize<'de>));
derive_trait(input, quote!{ ::serde::Deserialize<'de> }, &generics, || {
let tuple = each_field_except_unit(fields, unit, |name| {
quote! { #name, }
});
let body = derive_struct_body(fields, unit, |name| quote! { #name });
quote! {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: ::serde::Deserializer<'de>,
{
let (#tuple) = ::serde::Deserialize::deserialize(deserializer)?;
Ok(#body)
}
}
})
};
let serialize_impl = derive_simple_trait(input, quote! { ::serde::Serialize }, t, || {
let tuple = each_field_except_unit(fields, unit, |name| {
quote! { &self.#name, }
});
quote! {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: ::serde::Serializer,
{
(#tuple).serialize(serializer)
}
}
});
quote! {
#[cfg(feature = "serde")]
#serialize_impl
#[cfg(feature = "serde")]
#deserialize_impl
}
}
pub fn derive(input: DeriveInput) -> TokenStream {
let s = match input.data {
syn::Data::Struct(ref s) => s,
_ => panic!("Need to derive this on a struct"),
};
let fields = match s.fields {
syn::Fields::Named(ref named) => &named.named,
_ => panic!("Need to use named fields"),
};
assert!(!fields.is_empty());
let unit_field = fields.last().unwrap();
assert_eq!(
unit_field.value().ident.as_ref().unwrap().to_string(),
"_unit",
"You need to have a _unit field to derive this trait",
);
assert!(match unit_field.value().vis {
syn::Visibility::Public(..) => true,
_ => false,
}, "Unit field should be public");
assert!(input.attrs.iter().filter_map(|attr| attr.interpret_meta()).any(|attr| {
match attr {
syn::Meta::Word(..) |
syn::Meta::NameValue(..) => false,
syn::Meta::List(ref list) => {
list.ident == "repr" && list.nested.iter().any(|meta| {
match *meta {
syn::NestedMeta::Meta(syn::Meta::Word(ref w)) => w == "C",
_ => false,
}
})
}
}
}), "struct should be #[repr(C)]");
let type_param =
input.generics.type_params().next().cloned().expect("Need a T");
let clone = clone_impl(&input, fields, unit_field.value(), &type_param);
let copy = copy_impl(&input, &type_param);
let serde = serde_impl(&input, fields, unit_field.value(), &type_param);
let eq = eq_impl(&input, &type_param);
let partialeq = partialeq_impl(&input, fields, unit_field.value(), &type_param);
let hash = hash_impl(&input, fields, unit_field.value(), &type_param);
quote! {
#clone
#copy
#serde
#eq
#partialeq
#hash
}
}

16
third_party/rust/euclid_macros/lib.rs поставляемый
Просмотреть файл

@ -1,16 +0,0 @@
extern crate proc_macro;
extern crate proc_macro2;
#[macro_use]
extern crate quote;
#[macro_use]
extern crate syn;
use proc_macro::TokenStream;
mod euclid_matrix;
#[proc_macro_derive(EuclidMatrix)]
pub fn derive_euclid_matrix(input: TokenStream) -> TokenStream {
let input = syn::parse(input).unwrap();
euclid_matrix::derive(input).into()
}

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"73beabab6ca9844d6746f5946e01a97a60c9a4f0276076a9592265135bda649b","LICENSE":"b946744aeda89b467929585fe8eeb5461847695220c1b168fb375d8abd4ea3d0","README.md":"a65ed5c817c867fe23bc2029f34baea4a645a07dd5d101a0027e796d2923be58","benches/split.rs":"632a011dfc6d8235dea853785061b7bbfe0362eb85b91b3b01fbf77a7f1c7f26","src/bsp.rs":"2ccdca9bfc7d9a52621fcf91c441e924eb2068291b48daa8235ec000932a7790","src/clip.rs":"b58bb753b85b822eee2a0a88ea4eb5dff6a69276168ca61202486a6fb95eb95e","src/lib.rs":"57a6c885819b18ead087968937017b6330378bdcc10f285052c9d76e7a1b2226","src/polygon.rs":"e50f6671f953f6811f97a3b92e90e4a268c0d520e73528ba28a746f09e04c7ab","tests/clip.rs":"3335364fd6849697d3919084be5dce6c49acb31d8c53adc93a4cd05ee2ea93a9","tests/main.rs":"7c50a23d32eb8b0742bd533e98ba95c96110c4773b27ae0c40121c347feb9325","tests/split.rs":"88fe8192f8e0d03ac2b4b526c377ceeccbee4e3c35f4fa00be160d1402af09a2"},"package":"91c621d83b9c5a85b7ca7ca2bec643136debb327ad29d0a08768db1325780365"}
{"files":{"Cargo.toml":"2770453e4940bce81fed8d763daec0eecefcb4d14b1f296e467ef6ac22c24bfc","LICENSE":"b946744aeda89b467929585fe8eeb5461847695220c1b168fb375d8abd4ea3d0","README.md":"a65ed5c817c867fe23bc2029f34baea4a645a07dd5d101a0027e796d2923be58","benches/split.rs":"632a011dfc6d8235dea853785061b7bbfe0362eb85b91b3b01fbf77a7f1c7f26","src/bsp.rs":"964182582d53a160a86809231c61ba6512f38dde14b83c42b8145ef782064d30","src/clip.rs":"edb729a136706ad2e0d93fb8f79ec27ba9e1128d0debd2350e458d67beceb192","src/lib.rs":"aec71888fa99939b02e3fa3486817ce0d49d5bd5dc8e857fadbf7f48f24bf111","src/polygon.rs":"305af53f5d9334a10481f32ff60729e43e8c497d563c72e926b67dd7b68a261e","tests/clip.rs":"64e24fa6ea0ce05a7bfb837ef0e827f11a4c1c096cbac68283b74a2b32c47bb3","tests/main.rs":"238b0108b4605b8f7c77b2a886c9fb6ccb5ddc2644def166afb4eaedaec3a7c7","tests/split.rs":"f8f0784b9d2f1b3dbc0a0f25fc667ec3aa301b2ae4346f5b7ca0024c535570bc"},"package":"91821c7436aefc1b912552d494232efcaf9810c0189918749532be1e9dbace59"}

6
third_party/rust/plane-split/Cargo.toml поставляемый
Просмотреть файл

@ -3,7 +3,7 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g. crates.io) dependencies
# to registry (e.g., crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
@ -12,7 +12,7 @@
[package]
name = "plane-split"
version = "0.13.8"
version = "0.14.0"
authors = ["Dzmitry Malyshau <kvark@mozilla.com>"]
description = "Plane splitting"
documentation = "https://docs.rs/plane-split"
@ -23,7 +23,7 @@ repository = "https://github.com/servo/plane-split"
version = "0.1.2"
[dependencies.euclid]
version = "0.19"
version = "0.20"
[dependencies.log]
version = "0.4"

6
third_party/rust/plane-split/src/bsp.rs поставляемый
Просмотреть файл

@ -2,7 +2,7 @@ use {Intersection, Plane, Polygon, Splitter};
use is_zero;
use binary_space_partition::{BspNode, Plane as BspPlane, PlaneCut};
use euclid::{TypedPoint3D, TypedVector3D};
use euclid::{Point3D, Vector3D};
use euclid::approxeq::ApproxEq;
use num_traits::{Float, One, Zero};
@ -127,10 +127,10 @@ impl<T, U> Splitter<T, U> for BspSplitter<T, U> where
self.tree.insert(poly);
}
fn sort(&mut self, view: TypedVector3D<T, U>) -> &[Polygon<T, U>] {
fn sort(&mut self, view: Vector3D<T, U>) -> &[Polygon<T, U>] {
//debug!("\t\ttree before sorting {:?}", self.tree);
let poly = Polygon {
points: [TypedPoint3D::origin(); 4],
points: [Point3D::origin(); 4],
plane: Plane {
normal: -view, //Note: BSP `order()` is back to front
offset: T::zero(),

24
third_party/rust/plane-split/src/clip.rs поставляемый
Просмотреть файл

@ -1,6 +1,6 @@
use {Intersection, NegativeHemisphereError, Plane, Polygon};
use euclid::{Trig, TypedRect, TypedScale, TypedTransform3D, TypedVector3D};
use euclid::{Trig, Rect, Scale, Transform3D, Vector3D};
use euclid::approxeq::ApproxEq;
use num_traits::{Float, One, Zero};
@ -38,35 +38,35 @@ impl<
/// Extract the clipping planes that define the frustum for a given transformation.
pub fn frustum_planes<V>(
t: &TypedTransform3D<T, U, V>,
bounds: Option<TypedRect<T, V>>,
t: &Transform3D<T, U, V>,
bounds: Option<Rect<T, V>>,
) -> Result<impl Iterator<Item = Plane<T, U>>, NegativeHemisphereError> {
let mw = TypedVector3D::new(t.m14, t.m24, t.m34);
let mw = Vector3D::new(t.m14, t.m24, t.m34);
let plane_positive = Plane::from_unnormalized(mw, t.m44)?;
let bounds_iter_maybe = match bounds {
Some(bounds) => {
let mx = TypedVector3D::new(t.m11, t.m21, t.m31);
let mx = Vector3D::new(t.m11, t.m21, t.m31);
let left = bounds.origin.x;
let plane_left = Plane::from_unnormalized(
mx - mw * TypedScale::new(left),
mx - mw * Scale::new(left),
t.m41 - t.m44 * left,
)?;
let right = bounds.origin.x + bounds.size.width;
let plane_right = Plane::from_unnormalized(
mw * TypedScale::new(right) - mx,
mw * Scale::new(right) - mx,
t.m44 * right - t.m41,
)?;
let my = TypedVector3D::new(t.m12, t.m22, t.m32);
let my = Vector3D::new(t.m12, t.m22, t.m32);
let top = bounds.origin.y;
let plane_top = Plane::from_unnormalized(
my - mw * TypedScale::new(top),
my - mw * Scale::new(top),
t.m42 - t.m44 * top,
)?;
let bottom = bounds.origin.y + bounds.size.height;
let plane_bottom = Plane::from_unnormalized(
mw * TypedScale::new(bottom) - my,
mw * Scale::new(bottom) - my,
t.m44 * bottom - t.m42,
)?;
@ -130,8 +130,8 @@ impl<
pub fn clip_transformed<'a, V>(
&'a mut self,
polygon: Polygon<T, U>,
transform: &'a TypedTransform3D<T, U, V>,
bounds: Option<TypedRect<T, V>>,
transform: &'a Transform3D<T, U, V>,
bounds: Option<Rect<T, V>>,
) -> Result<impl 'a + Iterator<Item = Polygon<T, V>>, NegativeHemisphereError>
where
T: Trig,

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше