pub struct XPathScanner {
pub eo: bool,
pub x_min: i32,
pub x_max: i32,
pub y_min: i32,
pub y_max: i32,
/* private fields */
}Expand description
Per-scanline intersection table built from an XPath.
After construction the scanner is read-only; it is cheaply shareable via
Arc (matching the C++ shared_ptr<SplashXPathScanner> used in SplashClip).
§SoA layout invariant
row_start has length (y_max - y_min + 2) when non-empty: one entry per
scanline plus a sentinel at index n_rows. For any valid row index i:
row_start[i] <= row_start[i + 1] <= intersects.len()Intersections within each row are sorted in ascending x0 order.
Fields§
§eo: boolFill rule: true = even-odd, false = non-zero winding number.
x_min: i32Minimum device-pixel x-coordinate of any intersection in the table.
x_max: i32Maximum device-pixel x-coordinate of any intersection in the table.
y_min: i32First scanline (device-pixel y) covered by this scanner.
y_max: i32Last scanline (device-pixel y) covered by this scanner, inclusive.
Implementations§
Source§impl XPathScanner
impl XPathScanner
Sourcepub fn new(xpath: &XPath, eo: bool, clip_y_min: i32, clip_y_max: i32) -> Self
pub fn new(xpath: &XPath, eo: bool, clip_y_min: i32, clip_y_max: i32) -> Self
Build a scanner from xpath, clipping to [clip_y_min, clip_y_max].
If the xpath is empty or the y-ranges don’t overlap, returns an empty
scanner (is_empty() returns true).
§Panics
Panics if the number of rows after clamping overflows usize (cannot
happen for valid PDF coordinate ranges, as y_max - y_min + 1 is at
most i32::MAX).
Sourcepub fn nonempty_rows(&self) -> impl Iterator<Item = i32> + '_
pub fn nonempty_rows(&self) -> impl Iterator<Item = i32> + '_
Iterate over only the scanlines that have at least one intersection.
Skips empty rows using the row_start sentinel array — an empty row has
row_start[i] == row_start[i+1]. For paths that are sparse over the
bounding-box height (e.g., a thin diagonal across a tall page), this
eliminates the per-row overhead for all-empty rows.
Yields absolute device-pixel y values in ascending order.
Sourcepub fn row(&self, y: i32) -> &[Intersect]
pub fn row(&self, y: i32) -> &[Intersect]
The intersections for scanline y, sorted by x0.
Returns an empty slice if y is outside [y_min, y_max]. Never panics.
Sourcepub fn test_span(&self, x0: i32, x1: i32, y: i32) -> bool
pub fn test_span(&self, x0: i32, x1: i32, y: i32) -> bool
Test whether the entire span [x0, x1] on scanline y is inside the path.
Returns true only if every pixel in [x0, x1] is covered by the fill.
Sourcepub fn render_aa_line(
&self,
aa_buf: &mut AaBuf,
x0: &mut i32,
x1: &mut i32,
y: i32,
)
pub fn render_aa_line( &self, aa_buf: &mut AaBuf, x0: &mut i32, x1: &mut i32, y: i32, )
Render the AA supersampled row to aa_buf and update [x0, x1] output range.
Matches SplashXPathScanner::renderAALine. y is in device-pixel space;
the scanner must have been built from an aa_scale()’d XPath.
x0 and x1 are updated to the tightest bounding range of pixels
written into aa_buf. If no pixels are written, *x0 is set to 0
and *x1 to -1 (so *x0 > *x1 reliably indicates an empty range).
§Panics
Does not panic in practice. AA_SIZE is a positive compile-time constant
so all try_from conversions on loop indices succeed.