Path: blob/main/gpu_display/src/gpu_display_win/math_util.rs
5394 views
// Copyright 2022 The ChromiumOS Authors1// Use of this source code is governed by a BSD-style license that can be2// found in the LICENSE file.34use std::any::type_name;5use std::fmt;67use euclid::point2;8use euclid::size2;9use euclid::Size2D;10use num_traits::NumCast;11use winapi::shared::windef::LPPOINT;12use winapi::shared::windef::POINT;13use winapi::shared::windef::RECT;1415use super::HostWindowSpace;1617pub type Point = euclid::Point2D<i32, HostWindowSpace>;18pub type Rect = euclid::Rect<i32, HostWindowSpace>;19pub type Size = euclid::Size2D<i32, HostWindowSpace>;2021pub trait SizeExtension {22fn create_and_enforce_aspect_ratio(23original_size: &Self,24expected_aspect_ratio: f32,25should_adjust_width: bool,26) -> Self;27#[allow(dead_code)]28fn get_largest_inner_rect_size(original_size: &Self, expected_aspect_ratio: f32) -> Self;29#[allow(dead_code)]30fn scale(&self, ratio: f32) -> Self;31#[allow(dead_code)]32fn transpose(&self) -> Self;33#[allow(dead_code)]34fn shorter_edge(&self) -> i32;35fn aspect_ratio(&self) -> f32;36#[allow(dead_code)]37fn is_square(&self) -> bool;38#[allow(dead_code)]39fn is_landscape(&self) -> bool;40}4142impl SizeExtension for Size {43fn create_and_enforce_aspect_ratio(44original_size: &Self,45expected_aspect_ratio: f32,46should_adjust_width: bool,47) -> Self {48let mut size = *original_size;49if should_adjust_width {50size.width = (size.height as f32 * expected_aspect_ratio).round() as i32;51} else {52size.height = (size.width as f32 / expected_aspect_ratio).round() as i32;53}54size55}5657fn get_largest_inner_rect_size(original_size: &Self, expected_aspect_ratio: f32) -> Self {58Size::create_and_enforce_aspect_ratio(59original_size,60expected_aspect_ratio,61/* should_adjust_width */ original_size.aspect_ratio() > expected_aspect_ratio,62)63}6465#[inline]66fn scale(&self, ratio: f32) -> Self {67size2(68(self.width as f32 * ratio) as i32,69(self.height as f32 * ratio) as i32,70)71}7273#[inline]74fn transpose(&self) -> Self {75size2(self.height, self.width)76}7778#[inline]79fn shorter_edge(&self) -> i32 {80std::cmp::min(self.width, self.height)81}8283#[inline]84fn aspect_ratio(&self) -> f32 {85self.width as f32 / self.height as f3286}8788#[inline]89fn is_square(&self) -> bool {90self.width == self.height91}9293#[inline]94fn is_landscape(&self) -> bool {95self.width > self.height96}97}9899pub trait RectExtension {100fn to_sys_rect(&self) -> RECT;101}102103impl RectExtension for Rect {104#[inline]105fn to_sys_rect(&self) -> RECT {106RECT {107left: self.min_x(),108top: self.min_y(),109right: self.max_x(),110bottom: self.max_y(),111}112}113}114115pub trait SysRectExtension {116fn to_rect(&self) -> Rect;117}118119impl SysRectExtension for RECT {120#[inline]121fn to_rect(&self) -> Rect {122Rect::new(123point2(self.left, self.top),124size2(self.right - self.left, self.bottom - self.top),125)126}127}128129pub trait PointExtension {130fn to_sys_point(&self) -> POINT;131}132133impl PointExtension for Point {134#[inline]135fn to_sys_point(&self) -> POINT {136POINT {137x: self.x,138y: self.y,139}140}141}142143pub trait SysPointExtension {144fn to_point(&self) -> Point;145fn as_mut_ptr(&mut self) -> LPPOINT;146}147148impl SysPointExtension for POINT {149#[inline]150fn to_point(&self) -> Point {151point2(self.x, self.y)152}153154#[inline]155fn as_mut_ptr(&mut self) -> LPPOINT {156self as LPPOINT157}158}159160pub trait Size2DCheckedCast<U>: Sized {161fn checked_cast<T: NumCast>(self) -> Size2D<T, U>;162}163164impl<T, U> Size2DCheckedCast<U> for Size2D<T, U>165where166T: NumCast + Copy + fmt::Debug,167{168fn checked_cast<NewT: NumCast>(self) -> Size2D<NewT, U> {169self.try_cast::<NewT>().unwrap_or_else(|| {170panic!(171"Cannot cast {:?} from {} to {}",172self,173type_name::<T>(),174type_name::<NewT>(),175)176})177}178}179180#[cfg(test)]181mod tests {182use super::*;183184#[test]185fn largest_inner_rect_size_when_outer_is_wider() {186assert_eq!(187Size::get_largest_inner_rect_size(188/* original_size */ &size2(1600, 900),189/* expected_aspect_ratio */ 0.5190),191size2(450, 900)192);193}194195#[test]196fn largest_inner_rect_size_when_outer_is_taller() {197assert_eq!(198Size::get_largest_inner_rect_size(199/* original_size */ &size2(900, 1600),200/* expected_aspect_ratio */ 3.0201),202size2(900, 300)203);204}205}206207208