mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-30 04:58:34 -06:00
* M2: clip intersection starts its row walk at the first shared row clip::intersect in vello_common, the step every clipped path passes through, began its walk over strip rows at the earlier of the two paths' first rows. Each path therefore visited every row above it, although rows where one path has no strips produce no output. Every page is clipped (the crop box is a clip), so this ran for every stroke of every render: on the A1 engineering sample it was the hottest function in a full-page render. Start at the later first row, as vello_common 0.1 does. The strips and the pixels are unchanged; a test counts the rows the walk visits and fails without the change. vello_common 0.0.8 is vendored with that one-line PdfCraft patch (marked in the source), its unit test, the vendor/README.md row and an ATTRIBUTION.toml entry for its reference image. Cargo.lock records it as a path crate. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> * Refresh catalog hashes after merging main --------- Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com> Co-authored-by: Brandon Thomas <echelon@gmail.com>
109 lines
3.2 KiB
Rust
109 lines
3.2 KiB
Rust
// Copyright 2025 the Vello Authors
|
|
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
|
|
//! Geometry utilities.
|
|
|
|
/// An axis-aligned rectangle with `u16` coordinates, stored as two corners `(x0, y0)` and
|
|
/// `(x1, y1)`.
|
|
///
|
|
/// `(x0, y0)` is the top-left (minimum) corner and `(x1, y1)` is the bottom-right (maximum) corner.
|
|
/// The rectangle is considered to be empty when `x0 >= x1` or `y0 >= y1`.
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
pub struct RectU16 {
|
|
/// The minimum x coordinate (left edge).
|
|
pub x0: u16,
|
|
/// The minimum y coordinate (top edge).
|
|
pub y0: u16,
|
|
/// The maximum x coordinate (right edge, exclusive).
|
|
pub x1: u16,
|
|
/// The maximum y coordinate (bottom edge, exclusive).
|
|
pub y1: u16,
|
|
}
|
|
|
|
impl RectU16 {
|
|
/// A rectangle with all coordinates set to zero.
|
|
pub const ZERO: Self = Self {
|
|
x0: 0,
|
|
y0: 0,
|
|
x1: 0,
|
|
y1: 0,
|
|
};
|
|
|
|
/// An empty, maximally inverted rectangle, useful as a starting value for incremental union
|
|
/// operations.
|
|
///
|
|
/// Has `(x0, y0) = (u16::MAX, u16::MAX)` and `(x1, y1) = (0, 0)`.
|
|
pub const INVERTED: Self = Self {
|
|
x0: u16::MAX,
|
|
y0: u16::MAX,
|
|
x1: 0,
|
|
y1: 0,
|
|
};
|
|
|
|
/// Create a new rectangle from its corner coordinates.
|
|
#[inline(always)]
|
|
pub const fn new(x0: u16, y0: u16, x1: u16, y1: u16) -> Self {
|
|
Self { x0, y0, x1, y1 }
|
|
}
|
|
|
|
/// The width of the rectangle (`x1 - x0`), saturating at zero.
|
|
#[inline(always)]
|
|
pub const fn width(self) -> u16 {
|
|
self.x1.saturating_sub(self.x0)
|
|
}
|
|
|
|
/// The height of the rectangle (`y1 - y0`), saturating at zero.
|
|
#[inline(always)]
|
|
pub const fn height(self) -> u16 {
|
|
self.y1.saturating_sub(self.y0)
|
|
}
|
|
|
|
/// Returns `true` if the rectangle has zero area (`x0 >= x1` or `y0 >= y1`).
|
|
#[inline(always)]
|
|
pub const fn is_empty(self) -> bool {
|
|
self.x0 >= self.x1 || self.y0 >= self.y1
|
|
}
|
|
|
|
/// Check if a point `(x, y)` is contained within this rectangle.
|
|
///
|
|
/// Returns `true` if `x0 <= x < x1` and `y0 <= y < y1`.
|
|
#[inline(always)]
|
|
pub const fn contains(self, x: u16, y: u16) -> bool {
|
|
(x >= self.x0) & (x < self.x1) & (y >= self.y0) & (y < self.y1)
|
|
}
|
|
|
|
/// Compute the intersection of two rectangles.
|
|
///
|
|
/// The result may be empty if the rectangles do not overlap.
|
|
#[inline(always)]
|
|
pub const fn intersect(self, other: Self) -> Self {
|
|
Self {
|
|
x0: const_max(self.x0, other.x0),
|
|
y0: const_max(self.y0, other.y0),
|
|
x1: const_min(self.x1, other.x1),
|
|
y1: const_min(self.y1, other.y1),
|
|
}
|
|
}
|
|
|
|
/// Expand this rectangle to also cover `other` (union in place).
|
|
///
|
|
/// The union of `self` with a [`Self::INVERTED`] returns `self`.
|
|
#[inline(always)]
|
|
pub const fn union(&mut self, other: Self) {
|
|
self.x0 = const_min(self.x0, other.x0);
|
|
self.y0 = const_min(self.y0, other.y0);
|
|
self.x1 = const_max(self.x1, other.x1);
|
|
self.y1 = const_max(self.y1, other.y1);
|
|
}
|
|
}
|
|
|
|
#[inline(always)]
|
|
const fn const_max(a: u16, b: u16) -> u16 {
|
|
if a > b { a } else { b }
|
|
}
|
|
|
|
#[inline(always)]
|
|
const fn const_min(a: u16, b: u16) -> u16 {
|
|
if a < b { a } else { b }
|
|
}
|