tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

units.rs (12879B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 //! A collection of coordinate spaces and their corresponding Point, Size and Rect types.
      6 //!
      7 //! Physical pixels take into account the device pixel ratio and their dimensions tend
      8 //! to correspond to the allocated size of resources in memory, while logical pixels
      9 //! don't have the device pixel ratio applied which means they are agnostic to the usage
     10 //! of hidpi screens and the like.
     11 //!
     12 //! The terms "layer" and "stacking context" can be used interchangeably
     13 //! in the context of coordinate systems.
     14 
     15 pub use app_units::Au;
     16 use euclid::{Length, Rect, Scale, Size2D, Transform3D, Translation2D};
     17 use euclid::{Point2D, Point3D, Vector2D, Vector3D, SideOffsets2D, Box2D};
     18 use euclid::HomogeneousVector;
     19 use peek_poke::PeekPoke;
     20 // local imports
     21 use crate::image::DirtyRect;
     22 
     23 /// Geometry in the coordinate system of the render target (screen or intermediate
     24 /// surface) in physical pixels.
     25 #[derive(Hash, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
     26 pub struct DevicePixel;
     27 
     28 pub type DeviceIntRect = Box2D<i32, DevicePixel>;
     29 pub type DeviceIntPoint = Point2D<i32, DevicePixel>;
     30 pub type DeviceIntSize = Size2D<i32, DevicePixel>;
     31 pub type DeviceIntLength = Length<i32, DevicePixel>;
     32 pub type DeviceIntSideOffsets = SideOffsets2D<i32, DevicePixel>;
     33 pub type DeviceIntVector2D = Vector2D<i32, DevicePixel>;
     34 
     35 pub type DeviceRect = Box2D<f32, DevicePixel>;
     36 pub type DeviceBox2D = Box2D<f32, DevicePixel>;
     37 pub type DevicePoint = Point2D<f32, DevicePixel>;
     38 pub type DeviceVector2D = Vector2D<f32, DevicePixel>;
     39 pub type DeviceSize = Size2D<f32, DevicePixel>;
     40 pub type DeviceHomogeneousVector = HomogeneousVector<f32, DevicePixel>;
     41 
     42 /// Geometry in the coordinate system of the framebuffer in physical pixels.
     43 /// It's Y-flipped comparing to DevicePixel.
     44 #[derive(Hash, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
     45 pub struct FramebufferPixel;
     46 
     47 pub type FramebufferIntPoint = Point2D<i32, FramebufferPixel>;
     48 pub type FramebufferIntSize = Size2D<i32, FramebufferPixel>;
     49 pub type FramebufferIntRect = Box2D<i32, FramebufferPixel>;
     50 
     51 /// Geometry in the coordinate system of a Picture.
     52 #[derive(Hash, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
     53 pub struct PicturePixel;
     54 
     55 pub type PictureIntRect = Box2D<i32, PicturePixel>;
     56 pub type PictureIntPoint = Point2D<i32, PicturePixel>;
     57 pub type PictureIntSize = Size2D<i32, PicturePixel>;
     58 pub type PictureRect = Box2D<f32, PicturePixel>;
     59 pub type PicturePoint = Point2D<f32, PicturePixel>;
     60 pub type PictureSize = Size2D<f32, PicturePixel>;
     61 pub type PicturePoint3D = Point3D<f32, PicturePixel>;
     62 pub type PictureVector2D = Vector2D<f32, PicturePixel>;
     63 pub type PictureVector3D = Vector3D<f32, PicturePixel>;
     64 pub type PictureBox2D = Box2D<f32, PicturePixel>;
     65 
     66 /// Geometry gets rasterized in a given root coordinate space. This
     67 /// is often the root spatial node (world space), but may be a local
     68 /// space for a variety of reasons (e.g. perspective).
     69 #[derive(Hash, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
     70 pub struct RasterPixel;
     71 
     72 pub type RasterIntRect = Box2D<i32, RasterPixel>;
     73 pub type RasterIntPoint = Point2D<i32, RasterPixel>;
     74 pub type RasterIntSize = Size2D<i32, RasterPixel>;
     75 pub type RasterRect = Box2D<f32, RasterPixel>;
     76 pub type RasterPoint = Point2D<f32, RasterPixel>;
     77 pub type RasterSize = Size2D<f32, RasterPixel>;
     78 pub type RasterPoint3D = Point3D<f32, RasterPixel>;
     79 pub type RasterVector2D = Vector2D<f32, RasterPixel>;
     80 pub type RasterVector3D = Vector3D<f32, RasterPixel>;
     81 
     82 /// Geometry in a stacking context's local coordinate space (logical pixels).
     83 #[derive(Hash, Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, Ord, PartialOrd, Deserialize, Serialize, PeekPoke)]
     84 pub struct LayoutPixel;
     85 
     86 pub type LayoutRect = Box2D<f32, LayoutPixel>;
     87 pub type LayoutPoint = Point2D<f32, LayoutPixel>;
     88 pub type LayoutPoint3D = Point3D<f32, LayoutPixel>;
     89 pub type LayoutVector2D = Vector2D<f32, LayoutPixel>;
     90 pub type LayoutVector3D = Vector3D<f32, LayoutPixel>;
     91 pub type LayoutSize = Size2D<f32, LayoutPixel>;
     92 pub type LayoutSideOffsets = SideOffsets2D<f32, LayoutPixel>;
     93 
     94 pub type LayoutIntRect = Box2D<i32, LayoutPixel>;
     95 pub type LayoutIntPoint = Point2D<i32, LayoutPixel>;
     96 pub type LayoutIntSize = Size2D<i32, LayoutPixel>;
     97 
     98 /// Geometry in the document's coordinate space (logical pixels).
     99 #[derive(Hash, Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
    100 pub struct WorldPixel;
    101 
    102 pub type WorldRect = Box2D<f32, WorldPixel>;
    103 pub type WorldIntRect = Box2D<i32, WorldPixel>;
    104 pub type WorldPoint = Point2D<f32, WorldPixel>;
    105 pub type WorldSize = Size2D<f32, WorldPixel>;
    106 pub type WorldPoint3D = Point3D<f32, WorldPixel>;
    107 pub type WorldVector2D = Vector2D<f32, WorldPixel>;
    108 pub type WorldVector3D = Vector3D<f32, WorldPixel>;
    109 
    110 /// Geometry in the space in which we decided to perform visibility/clipping/invalidation
    111 /// calculations.
    112 /// This is intended to be a temporary type while transitioning some calculation from world
    113 /// to raster space.
    114 #[derive(Hash, Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, Ord, PartialOrd, Deserialize, Serialize, PeekPoke)]
    115 pub struct VisPixel;
    116 
    117 pub type VisRect = Box2D<f32, VisPixel>;
    118 
    119 /// TODO: Remove this once visibility rects have moved to raster space.
    120 pub fn vis_rect_as_world(r: VisRect) -> WorldRect {
    121    r.cast_unit()
    122 }
    123 
    124 
    125 /// Offset in number of tiles.
    126 #[derive(Hash, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
    127 pub struct Tiles;
    128 pub type TileOffset = Point2D<i32, Tiles>;
    129 pub type TileRange = Box2D<i32, Tiles>;
    130 
    131 /// Scaling ratio from world pixels to device pixels.
    132 pub type DevicePixelScale = Scale<f32, WorldPixel, DevicePixel>;
    133 /// Scaling ratio from layout to world. Used for cases where we know the layout
    134 /// is in world space, or specifically want to treat it this way.
    135 pub type LayoutToWorldScale = Scale<f32, LayoutPixel, WorldPixel>;
    136 /// A complete scaling ratio from layout space to device pixel space.
    137 pub type LayoutToDeviceScale = Scale<f32, LayoutPixel, DevicePixel>;
    138 
    139 pub type LayoutTransform = Transform3D<f32, LayoutPixel, LayoutPixel>;
    140 pub type LayoutToWorldTransform = Transform3D<f32, LayoutPixel, WorldPixel>;
    141 pub type WorldToLayoutTransform = Transform3D<f32, WorldPixel, LayoutPixel>;
    142 pub type LayoutToVisTransform = Transform3D<f32, LayoutPixel, VisPixel>;
    143 
    144 pub type LayoutToPictureTransform = Transform3D<f32, LayoutPixel, PicturePixel>;
    145 pub type PictureToLayoutTransform = Transform3D<f32, PicturePixel, LayoutPixel>;
    146 
    147 pub type LayoutToRasterTransform = Transform3D<f32, LayoutPixel, RasterPixel>;
    148 pub type RasterToLayoutTransform = Transform3D<f32, RasterPixel, LayoutPixel>;
    149 
    150 pub type PictureToRasterTransform = Transform3D<f32, PicturePixel, RasterPixel>;
    151 pub type RasterToPictureTransform = Transform3D<f32, RasterPixel, PicturePixel>;
    152 
    153 /// Scaling ratio from picture pixels to raster pixels (e.g. if scaling a picture surface up/down).
    154 pub type RasterPixelScale = Scale<f32, PicturePixel, RasterPixel>;
    155 
    156 // Fixed position coordinates, to avoid float precision errors.
    157 pub type LayoutPointAu = Point2D<Au, LayoutPixel>;
    158 pub type LayoutRectAu = Box2D<Au, LayoutPixel>;
    159 pub type LayoutSizeAu = Size2D<Au, LayoutPixel>;
    160 pub type LayoutVector2DAu = Vector2D<Au, LayoutPixel>;
    161 pub type LayoutSideOffsetsAu = SideOffsets2D<Au, LayoutPixel>;
    162 
    163 pub type ImageDirtyRect = DirtyRect<i32, DevicePixel>;
    164 pub type BlobDirtyRect = DirtyRect<i32, LayoutPixel>;
    165 
    166 pub type BlobToDeviceTranslation = Translation2D<i32, LayoutPixel, DevicePixel>;
    167 
    168 /// Stores two coordinates in texel space. The coordinates
    169 /// are stored in texel coordinates because the texture atlas
    170 /// may grow. Storing them as texel coords and normalizing
    171 /// the UVs in the vertex shader means nothing needs to be
    172 /// updated on the CPU when the texture size changes.
    173 #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
    174 #[repr(C)]
    175 pub struct TexelRect {
    176    pub uv0: DevicePoint,
    177    pub uv1: DevicePoint,
    178 }
    179 
    180 impl TexelRect {
    181    pub fn new(u0: f32, v0: f32, u1: f32, v1: f32) -> Self {
    182        TexelRect {
    183            uv0: DevicePoint::new(u0, v0),
    184            uv1: DevicePoint::new(u1, v1),
    185        }
    186    }
    187 
    188    pub fn invalid() -> Self {
    189        TexelRect {
    190            uv0: DevicePoint::new(-1.0, -1.0),
    191            uv1: DevicePoint::new(-1.0, -1.0),
    192        }
    193    }
    194 
    195    pub fn to_array(&self) -> [f32; 4] {
    196        [
    197            self.uv0.x,
    198            self.uv0.y,
    199            self.uv1.x,
    200            self.uv1.y,
    201        ]
    202    }
    203 }
    204 
    205 impl Into<TexelRect> for DeviceIntRect {
    206    fn into(self) -> TexelRect {
    207        TexelRect {
    208            uv0: self.min.to_f32(),
    209            uv1: self.max.to_f32(),
    210        }
    211    }
    212 }
    213 
    214 const MAX_AU_FLOAT: f32 = 1.0e6;
    215 
    216 pub trait AuHelpers<T> {
    217    fn from_au(data: T) -> Self;
    218    fn to_au(&self) -> T;
    219 }
    220 
    221 impl AuHelpers<LayoutSizeAu> for LayoutSize {
    222    fn from_au(size: LayoutSizeAu) -> Self {
    223        LayoutSize::new(
    224            size.width.to_f32_px(),
    225            size.height.to_f32_px(),
    226        )
    227    }
    228 
    229    fn to_au(&self) -> LayoutSizeAu {
    230        let width = self.width.min(2.0 * MAX_AU_FLOAT);
    231        let height = self.height.min(2.0 * MAX_AU_FLOAT);
    232 
    233        LayoutSizeAu::new(
    234            Au::from_f32_px(width),
    235            Au::from_f32_px(height),
    236        )
    237    }
    238 }
    239 
    240 impl AuHelpers<LayoutVector2DAu> for LayoutVector2D {
    241    fn from_au(size: LayoutVector2DAu) -> Self {
    242        LayoutVector2D::new(
    243            size.x.to_f32_px(),
    244            size.y.to_f32_px(),
    245        )
    246    }
    247 
    248    fn to_au(&self) -> LayoutVector2DAu {
    249        LayoutVector2DAu::new(
    250            Au::from_f32_px(self.x),
    251            Au::from_f32_px(self.y),
    252        )
    253    }
    254 }
    255 
    256 impl AuHelpers<LayoutPointAu> for LayoutPoint {
    257    fn from_au(point: LayoutPointAu) -> Self {
    258        LayoutPoint::new(
    259            point.x.to_f32_px(),
    260            point.y.to_f32_px(),
    261        )
    262    }
    263 
    264    fn to_au(&self) -> LayoutPointAu {
    265        let x = self.x.clamp(-MAX_AU_FLOAT, MAX_AU_FLOAT);
    266        let y = self.y.clamp(-MAX_AU_FLOAT, MAX_AU_FLOAT);
    267 
    268        LayoutPointAu::new(
    269            Au::from_f32_px(x),
    270            Au::from_f32_px(y),
    271        )
    272    }
    273 }
    274 
    275 impl AuHelpers<LayoutRectAu> for LayoutRect {
    276    fn from_au(rect: LayoutRectAu) -> Self {
    277        LayoutRect {
    278            min: LayoutPoint::from_au(rect.min),
    279            max: LayoutPoint::from_au(rect.max),
    280        }
    281    }
    282 
    283    fn to_au(&self) -> LayoutRectAu {
    284        LayoutRectAu {
    285            min: self.min.to_au(),
    286            max: self.max.to_au(),
    287        }
    288    }
    289 }
    290 
    291 impl AuHelpers<LayoutSideOffsetsAu> for LayoutSideOffsets {
    292    fn from_au(offsets: LayoutSideOffsetsAu) -> Self {
    293        LayoutSideOffsets::new(
    294            offsets.top.to_f32_px(),
    295            offsets.right.to_f32_px(),
    296            offsets.bottom.to_f32_px(),
    297            offsets.left.to_f32_px(),
    298        )
    299    }
    300 
    301    fn to_au(&self) -> LayoutSideOffsetsAu {
    302        LayoutSideOffsetsAu::new(
    303            Au::from_f32_px(self.top),
    304            Au::from_f32_px(self.right),
    305            Au::from_f32_px(self.bottom),
    306            Au::from_f32_px(self.left),
    307        )
    308    }
    309 }
    310 
    311 pub trait RectExt {
    312    type Point;
    313    fn top_left(&self) -> Self::Point;
    314    fn top_right(&self) -> Self::Point;
    315    fn bottom_left(&self) -> Self::Point;
    316    fn bottom_right(&self) -> Self::Point;
    317 }
    318 
    319 impl<U> RectExt for Rect<f32, U> {
    320    type Point = Point2D<f32, U>;
    321    fn top_left(&self) -> Self::Point {
    322        self.min()
    323    }
    324    fn top_right(&self) -> Self::Point {
    325        Point2D::new(self.max_x(), self.min_y())
    326    }
    327    fn bottom_left(&self) -> Self::Point {
    328        Point2D::new(self.min_x(), self.max_y())
    329    }
    330    fn bottom_right(&self) -> Self::Point {
    331        self.max()
    332    }
    333 }
    334 
    335 impl<U> RectExt for Box2D<f32, U> {
    336    type Point = Point2D<f32, U>;
    337    fn top_left(&self) -> Self::Point {
    338        self.min
    339    }
    340    fn top_right(&self) -> Self::Point {
    341        Point2D::new(self.max.x, self.min.y)
    342    }
    343    fn bottom_left(&self) -> Self::Point {
    344        Point2D::new(self.min.x, self.max.y)
    345    }
    346    fn bottom_right(&self) -> Self::Point {
    347        self.max
    348    }
    349 }
    350 
    351 // A few helpers to convert to cast between coordinate spaces that are often equivalent.
    352 
    353 #[inline]
    354 pub fn layout_rect_as_picture_rect(layout_rect: &LayoutRect) -> PictureRect {
    355    layout_rect.cast_unit()
    356 }
    357 
    358 #[inline]
    359 pub fn layout_vector_as_picture_vector(layout_vector: LayoutVector2D) -> PictureVector2D {
    360    layout_vector.cast_unit()
    361 }
    362 
    363 #[inline]
    364 pub fn device_size_as_framebuffer_size(framebuffer_size: DeviceIntSize) -> FramebufferIntSize {
    365    framebuffer_size.cast_unit()
    366 }
    367 
    368 #[inline]
    369 pub fn device_rect_as_framebuffer_rect(framebuffer_rect: &DeviceIntRect) -> FramebufferIntRect {
    370    framebuffer_rect.cast_unit()
    371 }