From: Ben Pfaff Date: Tue, 2 Dec 2025 16:27:24 +0000 (-0800) Subject: make plane locations signed X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ec7ffec8a64afd9b10f9ba7e97c7077ae77a3cab;p=pspp make plane locations signed --- diff --git a/rust/pspp/src/output/drivers/cairo.rs b/rust/pspp/src/output/drivers/cairo.rs index be8e528ed9..b1b34d5f13 100644 --- a/rust/pspp/src/output/drivers/cairo.rs +++ b/rust/pspp/src/output/drivers/cairo.rs @@ -25,11 +25,11 @@ pub mod pager; pub use driver::{CairoConfig, CairoDriver}; /// Conversion from 1/96" units ("pixels") to Cairo/Pango units. -fn px_to_xr(x: usize) -> usize { - x * 3 * (SCALE as usize * 72 / 96) / 3 +fn px_to_xr(x: isize) -> isize { + x * 3 * (SCALE as isize * 72 / 96) / 3 } -fn xr_to_pt(x: usize) -> f64 { +fn xr_to_pt(x: isize) -> f64 { x as f64 / SCALE as f64 } diff --git a/rust/pspp/src/output/drivers/cairo/driver.rs b/rust/pspp/src/output/drivers/cairo/driver.rs index eb04616a0b..1fa4c3e019 100644 --- a/rust/pspp/src/output/drivers/cairo/driver.rs +++ b/rust/pspp/src/output/drivers/cairo/driver.rs @@ -72,8 +72,8 @@ pub struct CairoDriver { impl CairoDriver { pub fn new(config: &CairoConfig) -> cairo::Result { - fn scale(inches: f64) -> usize { - (inches * 72.0 * SCALE as f64).max(0.0).round() as usize + fn scale(inches: f64) -> isize { + (inches * 72.0 * SCALE as f64).max(0.0).round() as isize } let default_page_setup; diff --git a/rust/pspp/src/output/drivers/cairo/fsm.rs b/rust/pspp/src/output/drivers/cairo/fsm.rs index b75479b7ae..83f3739e15 100644 --- a/rust/pspp/src/output/drivers/cairo/fsm.rs +++ b/rust/pspp/src/output/drivers/cairo/fsm.rs @@ -35,14 +35,14 @@ use crate::output::{Details, Item}; use crate::output::{pivot::Color, table::Content}; /// Width of an ordinary line. -const LINE_WIDTH: usize = LINE_SPACE / 2; +const LINE_WIDTH: isize = LINE_SPACE / 2; /// Space between double lines. -const LINE_SPACE: usize = SCALE as usize; +const LINE_SPACE: isize = SCALE as isize; /// Conversion from 1/96" units ("pixels") to Cairo/Pango units. -fn pxf_to_xr(x: f64) -> usize { - (x * (SCALE as f64 * 72.0 / 96.0)).round() as usize +fn pxf_to_xr(x: f64) -> isize { + (x * (SCALE as f64 * 72.0 / 96.0)).round() as isize } #[derive(Clone, Debug)] @@ -51,7 +51,7 @@ pub struct CairoFsmStyle { pub size: Coord2, /// Minimum cell size to allow breaking. - pub min_break: EnumMap, + pub min_break: EnumMap, /// The basic font. pub font: FontDescription, @@ -63,7 +63,7 @@ pub struct CairoFsmStyle { pub use_system_colors: bool, /// Vertical space between different output items. - pub object_spacing: usize, + pub object_spacing: isize, /// Resolution, in units per inch, used for measuring font "points": /// @@ -106,8 +106,8 @@ impl CairoFsm { layout.set_text("0"); let char_size = layout.size(); enum_map! { - Axis2::X => char_size.0.max(0) as usize, - Axis2::Y => char_size.1.max(0) as usize + Axis2::X => char_size.0 as isize, + Axis2::Y => char_size.1 as isize } }, line_widths: enum_map! { @@ -154,7 +154,7 @@ impl CairoFsm { } } - pub fn draw_slice(&mut self, context: &Context, space: usize) -> usize { + pub fn draw_slice(&mut self, context: &Context, space: isize) -> isize { debug_assert!(self.params.printing); context.save().unwrap(); @@ -167,7 +167,7 @@ impl CairoFsm { used } - fn draw_table(&mut self, context: &Context, space: usize) -> usize { + fn draw_table(&mut self, context: &Context, space: isize) -> isize { let Details::Table(pivot_table) = &self.item.details else { unreachable!() }; @@ -211,7 +211,7 @@ impl CairoFsm { } fn xr_clip(context: &Context, clip: &Rect2) { - if clip[Axis2::X].end != usize::MAX || clip[Axis2::Y].end != usize::MAX { + if clip[Axis2::X].end != isize::MAX || clip[Axis2::Y].end != isize::MAX { let x0 = xr_to_pt(clip[Axis2::X].start); let y0 = xr_to_pt(clip[Axis2::Y].start); let x1 = xr_to_pt(clip[Axis2::X].end); @@ -240,14 +240,14 @@ fn xr_fill_rectangle(context: &Context, rectangle: Rect2) { let x0 = xr_to_pt(rectangle[Axis2::X].start); let y0 = xr_to_pt(rectangle[Axis2::Y].start); - let width = xr_to_pt(rectangle[Axis2::X].len()); - let height = xr_to_pt(rectangle[Axis2::Y].len()); + let width = xr_to_pt(rectangle[Axis2::X].len() as isize); + let height = xr_to_pt(rectangle[Axis2::Y].len() as isize); context.rectangle(x0, y0, width, height); context.fill().unwrap(); } -fn margin(cell: &DrawCell, axis: Axis2) -> usize { - px_to_xr(cell.cell_style.margins[axis].iter().sum::().max(0) as usize) +fn margin(cell: &DrawCell, axis: Axis2) -> isize { + px_to_xr(cell.cell_style.margins[axis].iter().sum::() as isize) } pub fn parse_font_style(font_style: &FontStyle) -> FontDescription { @@ -341,7 +341,7 @@ impl<'a, 'b> DrawCell<'a, 'b> { let decimal_position = if let Some(position) = body.rfind(char::from(decimal)) { layout.set_text(&body[position..]); layout.set_width(-1); - layout.size().0.max(0) as usize + layout.size().0 as isize } else { 0 }; @@ -382,10 +382,10 @@ impl<'a, 'b> DrawCell<'a, 'b> { footnote_attrs.insert(AttrFloat::new_scale(SCALE_SMALL)); footnote_attrs.insert(AttrInt::new_rise(3000)); layout.set_attributes(Some(&footnote_attrs)); - let footnote_width = layout.size().0.max(0) as usize; + let footnote_width = layout.size().0 as isize; // Bound the adjustment by the width of the right margin. - let right_margin = px_to_xr(self.cell_style.margins[Axis2::X][1].max(0) as usize); + let right_margin = px_to_xr(self.cell_style.margins[Axis2::X][1] as isize); let footnote_adjustment = min(footnote_width, right_margin); // Adjust the bounding box. @@ -427,7 +427,7 @@ impl<'a, 'b> DrawCell<'a, 'b> { layout.set_attributes(attrs.as_ref()); layout.set_text(&body); layout.set_alignment(horz_align.into()); - if bb[Axis2::X].end == usize::MAX { + if bb[Axis2::X].end == isize::MAX { layout.set_width(-1); } else { layout.set_width(bb[Axis2::X].len() as i32); @@ -448,9 +448,7 @@ impl<'a, 'b> DrawCell<'a, 'b> { xr_clip(context, clip); } if self.rotate { - let extra = bb[Axis2::X] - .len() - .saturating_sub(layout.size().1.max(0) as usize); + let extra = (bb[Axis2::X].len() as isize - layout.size().1 as isize).max(0); let halign_offset = extra / 2; context.translate( xr_to_pt(bb[Axis2::X].start + halign_offset), @@ -476,7 +474,7 @@ impl CairoDevice<'_> { let mut layout = self.style.new_layout(self.context); cell.layout(&bb, &mut layout, &self.style.font); let (width, height) = layout.size(); - Coord2::new(width.max(0) as usize, height.max(0) as usize) + Coord2::new(width as isize, height as isize) } fn cell_draw(&self, cell: &DrawCell, bb: Rect2, clip: &Rect2) { @@ -487,10 +485,10 @@ impl CairoDevice<'_> { fn do_draw_line( &self, - x0: usize, - y0: usize, - x1: usize, - y1: usize, + x0: isize, + y0: isize, + x1: isize, + y1: isize, stroke: Stroke, color: Color, ) { @@ -520,8 +518,8 @@ impl Device for CairoDevice<'_> { self.params } - fn measure_cell_width(&self, cell: &DrawCell) -> EnumMap { - fn add_margins(cell: &DrawCell, width: usize) -> usize { + fn measure_cell_width(&self, cell: &DrawCell) -> EnumMap { + fn add_margins(cell: &DrawCell, width: isize) -> isize { if width > 0 { width + margin(cell, Axis2::X) } else { @@ -531,26 +529,26 @@ impl Device for CairoDevice<'_> { enum_map![ Extreme::Min => { - let bb = Rect2::new(0..1, 0..usize::MAX); + let bb = Rect2::new(0..1, 0..isize::MAX); add_margins(cell, self.measure_cell(cell, bb).x()) } Extreme::Max => { - let bb = Rect2::new(0..usize::MAX, 0..usize::MAX); + let bb = Rect2::new(0..isize::MAX, 0..isize::MAX); add_margins(cell, self.measure_cell(cell, bb).x()) }, ] } - fn measure_cell_height(&self, cell: &DrawCell, width: usize) -> usize { + fn measure_cell_height(&self, cell: &DrawCell, width: isize) -> isize { let margins = &cell.cell_style.margins; let bb = Rect2::new( - 0..width.saturating_sub(px_to_xr(margins[Axis2::X].len())), - 0..usize::MAX, + 0..width.saturating_sub(px_to_xr(margins[Axis2::X].len() as isize)), + 0..isize::MAX, ); self.measure_cell(cell, bb).y() + margin(cell, Axis2::Y) } - fn adjust_break(&self, _cell: &Content, _size: Coord2) -> usize { + fn adjust_break(&self, _cell: &Content, _size: Coord2) -> isize { todo!() } @@ -707,8 +705,8 @@ impl Device for CairoDevice<'_> { &mut self, draw_cell: &DrawCell, mut bb: Rect2, - valign_offset: usize, - spill: EnumMap, + valign_offset: isize, + spill: EnumMap, clip: &Rect2, ) { let bg = draw_cell.font_style.bg; @@ -744,10 +742,10 @@ impl Device for CairoDevice<'_> { self.context.save().unwrap(); bb[Axis2::Y].start += valign_offset; for axis in [Axis2::X, Axis2::Y] { - bb[axis].start += px_to_xr(draw_cell.cell_style.margins[axis][0].max(0) as usize); + bb[axis].start += px_to_xr(draw_cell.cell_style.margins[axis][0] as isize); bb[axis].end = bb[axis] .end - .saturating_sub(draw_cell.cell_style.margins[axis][0].max(0) as usize); + .saturating_sub(draw_cell.cell_style.margins[axis][0] as isize); } if bb[Axis2::X].start < bb[Axis2::X].end && bb[Axis2::Y].start < bb[Axis2::Y].end { self.cell_draw(draw_cell, bb, clip); diff --git a/rust/pspp/src/output/drivers/cairo/pager.rs b/rust/pspp/src/output/drivers/cairo/pager.rs index 1f099f537c..1ca673e3db 100644 --- a/rust/pspp/src/output/drivers/cairo/pager.rs +++ b/rust/pspp/src/output/drivers/cairo/pager.rs @@ -33,7 +33,7 @@ use crate::output::{ #[derive(Clone, Debug)] pub struct CairoPageStyle { - pub margins: EnumMap, + pub margins: EnumMap, pub header: Document, pub footer: Document, pub initial_page_number: i32, @@ -46,8 +46,8 @@ pub struct CairoPager { item: Option>, context: Option, fsm: Option, - y: usize, - y_max: usize, + y: isize, + y_max: isize, } impl CairoPager { @@ -154,7 +154,7 @@ impl CairoPager { self.fsm = None; } else if chunk == 0 { assert!(self.y > 0); - self.y = usize::MAX; + self.y = isize::MAX; return; } } @@ -165,7 +165,7 @@ struct RenderHeading<'a, F> { heading: &'a Document, fsm_style: &'a CairoFsmStyle, page_number: i32, - width: usize, + width: isize, font_resolution: f64, substitutions: F, } @@ -178,13 +178,13 @@ where Self { heading, ..self } } - fn measure(&self) -> usize { + fn measure(&self) -> isize { let surface = RecordingSurface::create(cairo::Content::Color, None).unwrap(); let context = Context::new(&surface).unwrap(); self.render(&context, 0) } - fn render(&self, context: &Context, base_y: usize) -> usize { + fn render(&self, context: &Context, base_y: isize) -> isize { let pangocairo_context = pangocairo::functions::create_context(context); pangocairo::functions::context_set_resolution(&pangocairo_context, self.font_resolution); @@ -208,10 +208,10 @@ where substitutions, }; let mut layout = Layout::new(&pangocairo_context); - let bb = Rect2::new(0..self.width, y + base_y..usize::MAX); + let bb = Rect2::new(0..self.width, y + base_y..isize::MAX); cell.layout(&bb, &mut layout, &self.fsm_style.font); cell.draw(&bb, &layout, None, context); - y += layout.size().1 as usize; + y += layout.size().1 as isize; } if y > 0 { y + self.fsm_style.object_spacing diff --git a/rust/pspp/src/output/drivers/text.rs b/rust/pspp/src/output/drivers/text.rs index 9b18ac44ad..d930a0cc39 100644 --- a/rust/pspp/src/output/drivers/text.rs +++ b/rust/pspp/src/output/drivers/text.rs @@ -87,7 +87,7 @@ pub struct TextRenderer { emphasis: bool, /// Page width. - width: usize, + width: isize, /// Minimum cell size to break across pages. min_hbreak: usize, @@ -107,7 +107,7 @@ impl Default for TextRenderer { impl TextRenderer { pub fn new(config: &TextRendererOptions) -> Self { - let width = config.width.unwrap_or(usize::MAX); + let width = config.width.unwrap_or(usize::MAX).min(isize::MAX as usize) as isize; Self { emphasis: config.emphasis, width, @@ -115,13 +115,13 @@ impl TextRenderer { box_chars: config.boxes.box_chars(), n_objects: 0, params: Params { - size: Coord2::new(width, usize::MAX), + size: Coord2::new(width, isize::MAX), font_size: EnumMap::from_fn(|_| 1), line_widths: EnumMap::from_fn(|stroke| if stroke == Stroke::None { 0 } else { 1 }), px_size: None, min_break: enum_map! { Axis2::X => width / 2, - Axis2::Y => usize::MAX, + Axis2::Y => isize::MAX, }, supports_margins: false, rtl: false, @@ -416,7 +416,7 @@ impl TextRenderer { let mut pager = Pager::new(self, table, Some(layer_indexes.as_slice())); while pager.has_next(self) { - pager.draw_next(self, usize::MAX); + pager.draw_next(self, isize::MAX); for line in self.lines.drain(..) { writeln!(writer, "{line}")?; } @@ -434,7 +434,7 @@ impl TextRenderer { let breaks = new_line_breaks(text, bb[X].len()); let mut size = Coord2::new(0, 0); for text in breaks.take(bb[Y].len()) { - let width = text.width(); + let width = text.width() as isize; if width > size[X] { size[X] = width; } @@ -576,21 +576,21 @@ impl Device for TextRenderer { &self.params } - fn measure_cell_width(&self, cell: &DrawCell) -> EnumMap { + fn measure_cell_width(&self, cell: &DrawCell) -> EnumMap { let text = cell.display().to_string(); enum_map![ - Extreme::Min => self.layout_cell(&text, Rect2::new(0..1, 0..usize::MAX)).x(), - Extreme::Max => self.layout_cell(&text, Rect2::new(0..usize::MAX, 0..usize::MAX)).x(), + Extreme::Min => self.layout_cell(&text, Rect2::new(0..1, 0..isize::MAX)).x(), + Extreme::Max => self.layout_cell(&text, Rect2::new(0..isize::MAX, 0..isize::MAX)).x(), ] } - fn measure_cell_height(&self, cell: &DrawCell, width: usize) -> usize { + fn measure_cell_height(&self, cell: &DrawCell, width: isize) -> isize { let text = cell.display().to_string(); - self.layout_cell(&text, Rect2::new(0..width, 0..usize::MAX)) + self.layout_cell(&text, Rect2::new(0..width, 0..isize::MAX)) .y() } - fn adjust_break(&self, _cell: &Content, _size: Coord2) -> usize { + fn adjust_break(&self, _cell: &Content, _size: Coord2) -> isize { unreachable!() } @@ -610,7 +610,8 @@ impl Device for TextRenderer { }; let c = self.box_chars[lines]; for y in y { - self.get_line(y).put_multiple(x.start, c, x.len()); + self.get_line(y as usize) + .put_multiple(x.start as usize, c, x.len()); } } @@ -618,8 +619,8 @@ impl Device for TextRenderer { &mut self, cell: &DrawCell, bb: Rect2, - valign_offset: usize, - _spill: EnumMap, + valign_offset: isize, + _spill: EnumMap, clip: &Rect2, ) { let display = cell.display(); @@ -629,15 +630,15 @@ impl Device for TextRenderer { use Axis2::*; let breaks = new_line_breaks(&text, bb[X].len()); for (text, y) in breaks.zip(bb[Y].start + valign_offset..bb[Y].end) { - let width = text.width(); - if !clip[Y].contains(&y) { + let width = text.width() as isize; + if y < 0 || !clip[Y].contains(&y) { continue; } let x = match horz_align { HorzAlign::Right | HorzAlign::Decimal { .. } => bb[X].end - width, HorzAlign::Left => bb[X].start, - HorzAlign::Center => (bb[X].start + bb[X].end - width).div_ceil(2), + HorzAlign::Center => ((bb[X].start + bb[X].end - width) + 1) / 2, }; let Some((x, text)) = clip_text(text, &(x..x + width), &clip[X]) else { continue; @@ -648,7 +649,7 @@ impl Device for TextRenderer { } else { Cow::from(text) }; - self.get_line(y).put(x, &text); + self.get_line(y as usize).put(x as usize, &text); } } diff --git a/rust/pspp/src/output/drivers/text/text_line.rs b/rust/pspp/src/output/drivers/text/text_line.rs index e4d7c5c370..b986163011 100644 --- a/rust/pspp/src/output/drivers/text/text_line.rs +++ b/rust/pspp/src/output/drivers/text/text_line.rs @@ -300,18 +300,22 @@ impl Debug for Emphasis { pub fn clip_text<'a>( text: &'a str, - bb: &Range, - clip: &Range, -) -> Option<(usize, &'a str)> { + bb: &Range, + clip: &Range, +) -> Option<(isize, &'a str)> { let mut x = bb.start; - let mut width = bb.len(); + let mut width = bb.len() as isize; let mut iter = text.chars(); while x < clip.start { let c = iter.next()?; if let Some(w) = c.width() { + let w = w as isize; x += w; - width = width.checked_sub(w)?; + width -= w; + if width < 0 { + return None; + } } } if x + width > clip.end { @@ -322,7 +326,10 @@ pub fn clip_text<'a>( while x + width > clip.end { let c = iter.next_back()?; if let Some(w) = c.width() { - width = width.checked_sub(w)?; + width -= w as isize; + if width < 0 { + return None; + } } } } diff --git a/rust/pspp/src/output/pivot.rs b/rust/pspp/src/output/pivot.rs index 6e8c90960a..1c14d1c819 100644 --- a/rust/pspp/src/output/pivot.rs +++ b/rust/pspp/src/output/pivot.rs @@ -949,7 +949,7 @@ pub struct Look { pub row_label_position: LabelPosition, /// Ranges of column widths in the two heading regions, in 1/96" units. - pub heading_widths: EnumMap>, + pub heading_widths: EnumMap>, /// Kind of markers to use for footnotes. pub footnote_marker_type: FootnoteMarkerType, @@ -1667,10 +1667,10 @@ impl IndexMut for Index2 { /// A 2-dimensional `(x,y)` pair. #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)] -pub struct Coord2(pub EnumMap); +pub struct Coord2(pub EnumMap); impl Coord2 { - pub fn new(x: usize, y: usize) -> Self { + pub fn new(x: isize, y: isize) -> Self { use Axis2::*; Self(enum_map! { X => x, @@ -1678,7 +1678,7 @@ impl Coord2 { }) } - pub fn for_axis((a, az): (Axis2, usize), bz: usize) -> Self { + pub fn for_axis((a, az): (Axis2, isize), bz: isize) -> Self { let mut coord = Self::default(); coord[a] = az; coord[!a] = bz; @@ -1687,32 +1687,32 @@ impl Coord2 { pub fn from_fn(f: F) -> Self where - F: FnMut(Axis2) -> usize, + F: FnMut(Axis2) -> isize, { Self(EnumMap::from_fn(f)) } - pub fn x(&self) -> usize { + pub fn x(&self) -> isize { self.0[Axis2::X] } - pub fn y(&self) -> usize { + pub fn y(&self) -> isize { self.0[Axis2::Y] } - pub fn get(&self, axis: Axis2) -> usize { + pub fn get(&self, axis: Axis2) -> isize { self.0[axis] } } -impl From> for Coord2 { - fn from(value: EnumMap) -> Self { +impl From> for Coord2 { + fn from(value: EnumMap) -> Self { Self(value) } } impl Index for Coord2 { - type Output = usize; + type Output = isize; fn index(&self, index: Axis2) -> &Self::Output { &self.0[index] @@ -1726,10 +1726,10 @@ impl IndexMut for Coord2 { } #[derive(Clone, Debug, Default)] -pub struct Rect2(pub EnumMap>); +pub struct Rect2(pub EnumMap>); impl Rect2 { - pub fn new(x_range: Range, y_range: Range) -> Self { + pub fn new(x_range: Range, y_range: Range) -> Self { Self(enum_map! { Axis2::X => x_range.clone(), Axis2::Y => y_range.clone(), @@ -1738,7 +1738,7 @@ impl Rect2 { pub fn for_cell(cell: Coord2) -> Self { Self::new(cell.x()..cell.x() + 1, cell.y()..cell.y() + 1) } - pub fn for_ranges((a, a_range): (Axis2, Range), b_range: Range) -> Self { + pub fn for_ranges((a, a_range): (Axis2, Range), b_range: Range) -> Self { let b = !a; let mut ranges = EnumMap::default(); ranges[a] = a_range; @@ -1751,7 +1751,7 @@ impl Rect2 { } pub fn from_fn(f: F) -> Self where - F: FnMut(Axis2) -> Range, + F: FnMut(Axis2) -> Range, { Self(EnumMap::from_fn(f)) } @@ -1763,14 +1763,14 @@ impl Rect2 { } } -impl From>> for Rect2 { - fn from(value: EnumMap>) -> Self { +impl From>> for Rect2 { + fn from(value: EnumMap>) -> Self { Self(value) } } impl Index for Rect2 { - type Output = Range; + type Output = Range; fn index(&self, index: Axis2) -> &Self::Output { &self.0[index] diff --git a/rust/pspp/src/output/pivot/tlo.rs b/rust/pspp/src/output/pivot/tlo.rs index b83526186a..39c6c3240d 100644 --- a/rust/pspp/src/output/pivot/tlo.rs +++ b/rust/pspp/src/output/pivot/tlo.rs @@ -53,7 +53,7 @@ pub fn parse_tlo(input: &[u8]) -> BinResult { } /// Points (72/inch) to pixels (96/inch). -fn pt_to_px(pt: i32) -> usize { +fn pt_to_px(pt: i32) -> isize { num::cast((pt as f64 * (96.0 / 72.0)).round()).unwrap_or_default() } @@ -63,7 +63,7 @@ fn px_to_pt(px: i32) -> i32 { } /// 20ths of a point to pixels (96/inch). -fn pt20_to_px(pt20: i32) -> usize { +fn pt20_to_px(pt20: i32) -> isize { num::cast((pt20 as f64 * (96.0 / 72.0 / 20.0)).round()).unwrap_or_default() } diff --git a/rust/pspp/src/output/render.rs b/rust/pspp/src/output/render.rs index 14a5959621..8a687ca836 100644 --- a/rust/pspp/src/output/render.rs +++ b/rust/pspp/src/output/render.rs @@ -51,20 +51,20 @@ pub struct Params { /// Nominal size of a character in the most common font: /// `font_size[Axis2::X]` is the em width. /// `font_size[Axis2::Y]` is the line leading. - pub font_size: EnumMap, + pub font_size: EnumMap, /// Width of different kinds of lines. - pub line_widths: EnumMap, + pub line_widths: EnumMap, /// 1/96" of an inch (1px) in the rendering unit. Currently used only for /// column width ranges, as in `width_ranges` in /// [crate::output::pivot::Look]. Set to `None` to disable this feature. - pub px_size: Option, + pub px_size: Option, /// Minimum cell width or height before allowing the cell to be broken /// across two pages. (Joined cells may always be broken at join /// points.) - pub min_break: EnumMap, + pub min_break: EnumMap, /// True if the driver supports cell margins. (If false, the rendering /// engine will insert a small space betweeen adjacent cells that don't have @@ -88,7 +88,7 @@ pub struct Params { impl Params { /// Returns a small but visible width. - fn em(&self) -> usize { + fn em(&self) -> isize { self.font_size[Axis2::X] } } @@ -110,10 +110,10 @@ pub trait Device { /// /// - `map[Extreme::Max]` is the minimum width required to avoid line breaks /// other than at new-lines. - fn measure_cell_width(&self, cell: &DrawCell) -> EnumMap; + fn measure_cell_width(&self, cell: &DrawCell) -> EnumMap; /// Returns the height required to render `cell` given a width of `width`. - fn measure_cell_height(&self, cell: &DrawCell, width: usize) -> usize; + fn measure_cell_height(&self, cell: &DrawCell, width: isize) -> isize; /// Given that there is space measuring `size` to render `cell`, where /// `size.y()` is insufficient to render the entire height of the cell, @@ -125,7 +125,7 @@ pub trait Device { /// /// Optional. If [Params::can_adjust_break] is false, the rendering engine /// assumes that all breakpoints are acceptable. - fn adjust_break(&self, cell: &Content, size: Coord2) -> usize; + fn adjust_break(&self, cell: &Content, size: Coord2) -> isize; /// Draws a generalized intersection of lines in `bb`. /// @@ -152,8 +152,8 @@ pub trait Device { &mut self, draw_cell: &DrawCell, bb: Rect2, - valign_offset: usize, - spill: EnumMap, + valign_offset: isize, + spill: EnumMap, clip: &Rect2, ); @@ -222,7 +222,7 @@ struct Page { /// /// Rules and columns can have width or height 0, in which case consecutive /// values in this array are equal. - cp: EnumMap>, + cp: EnumMap>, /// [Break::next] can break a [Page] in the middle of a cell, if a cell is /// too wide or two tall to fit on a single page, or if a cell spans @@ -293,7 +293,7 @@ struct Page { /// ``` /// Each entry maps from a cell that overflows to the space that has been /// trimmed off the cell. - overflows: HashMap>, + overflows: HashMap>, /// If a single column (or row) is too wide (or tall) to fit on a page /// reasonably, then [Break::next] will split a single row or column across @@ -317,12 +317,12 @@ struct Page { } /// Returns the width of `extent` along `axis`. -fn axis_width(cp: &[usize], extent: Range) -> usize { +fn axis_width(cp: &[isize], extent: Range) -> isize { cp[extent.end] - cp[extent.start] } /// Returns the width of cells within `extent` along `axis`. -fn joined_width(cp: &[usize], extent: Range) -> usize { +fn joined_width(cp: &[isize], extent: Range) -> isize { axis_width(cp, cell_ofs(extent.start)..cell_ofs(extent.end) - 1) } /// Returns the offset in [Self::cp] of the cell with index `cell_index`. @@ -342,7 +342,7 @@ fn rule_ofs(rule_index: usize) -> usize { } /// Returns the width of cell `z` along `axis`. -fn cell_width(cp: &[usize], z: usize) -> usize { +fn cell_width(cp: &[isize], z: usize) -> isize { let ofs = cell_ofs(z); axis_width(cp, ofs..ofs + 1) } @@ -365,7 +365,7 @@ impl Page { /// The new [Page] will be suitable for rendering on a device whose page /// size is `params.size`, but the caller is responsible for actually /// breaking it up to fit on such a device, using the [Break] abstraction. - fn new(table: Arc, device: &dyn Device, min_width: usize, look: &Look) -> Self { + fn new(table: Arc
, device: &dyn Device, min_width: isize, look: &Look) -> Self { use Axis2::*; use Extreme::*; @@ -455,8 +455,8 @@ impl Page { } // Decide final column widths. - let rule_widths = rules[X].iter().copied().sum::(); - let table_widths = EnumMap::from_fn(|ext| columns[ext].iter().sum::() + rule_widths); + let rule_widths = rules[X].iter().copied().sum::(); + let table_widths = EnumMap::from_fn(|ext| columns[ext].iter().sum::() + rule_widths); let cp_x = if table_widths[Max] <= device.params().size[X] { // Fits even with maximum widths. Use them. @@ -533,7 +533,7 @@ impl Page { } } - fn use_row_widths(rows: &[usize], rules: &[usize]) -> Vec { + fn use_row_widths(rows: &[isize], rules: &[isize]) -> Vec { let mut vec = once(0) .chain(interleave(rules, rows).copied()) .collect::>(); @@ -544,11 +544,11 @@ impl Page { } fn interpolate_column_widths( - target: usize, - columns: &EnumMap>, - widths: &EnumMap, - rules: &[usize], - ) -> Vec { + target: isize, + columns: &EnumMap>, + widths: &EnumMap, + rules: &[isize], + ) -> Vec { use Extreme::*; let avail = target - widths[Min]; @@ -566,28 +566,28 @@ impl Page { } /// Returns the width of `extent` along `axis`. - fn axis_width(&self, axis: Axis2, extent: Range) -> usize { + fn axis_width(&self, axis: Axis2, extent: Range) -> isize { axis_width(&self.cp[axis], extent) } /// Returns the width of cells within `extent` along `axis`. - fn joined_width(&self, axis: Axis2, extent: Range) -> usize { + fn joined_width(&self, axis: Axis2, extent: Range) -> isize { joined_width(&self.cp[axis], extent) } /// Returns the width of the headers along `axis`. - fn headers_width(&self, axis: Axis2) -> usize { + fn headers_width(&self, axis: Axis2) -> isize { self.axis_width(axis, rule_ofs(0)..cell_ofs(self.h[axis])) } /// Returns the width of rule `z` along `axis`. - fn rule_width(&self, axis: Axis2, z: usize) -> usize { + fn rule_width(&self, axis: Axis2, z: usize) -> isize { let ofs = rule_ofs(z); self.axis_width(axis, ofs..ofs + 1) } /// Returns the width of rule `z` along `axis`, counting in reverse order. - fn rule_width_r(&self, axis: Axis2, z: usize) -> usize { + fn rule_width_r(&self, axis: Axis2, z: usize) -> isize { let ofs = self.rule_ofs_r(axis, z); self.axis_width(axis, ofs..ofs + 1) } @@ -603,20 +603,20 @@ impl Page { } /// Returns the width of cell `z` along `axis`. - fn cell_width(&self, axis: Axis2, z: usize) -> usize { + fn cell_width(&self, axis: Axis2, z: usize) -> isize { let ofs = cell_ofs(z); self.axis_width(axis, ofs..ofs + 1) } /// Returns the width of the widest cell, excluding headers, along `axis`. - fn max_cell_width(&self, axis: Axis2) -> usize { + fn max_cell_width(&self, axis: Axis2) -> isize { (self.h[axis]..self.n[axis]) .map(|z| self.cell_width(axis, z)) .max() .unwrap_or(0) } - fn width(&self, axis: Axis2) -> usize { + fn width(&self, axis: Axis2) -> isize { *self.cp[axis].last().unwrap() } @@ -683,8 +683,8 @@ impl Page { self: &Arc, a: Axis2, extent: Range, - pixel0: usize, - pixel1: usize, + pixel0: isize, + pixel1: isize, ) -> Arc { let b = !a; let z0 = extent.start; @@ -830,7 +830,7 @@ impl Page { }) } - fn total_size(&self, axis: Axis2) -> usize { + fn total_size(&self, axis: Axis2) -> isize { self.cp[axis].last().copied().unwrap() } @@ -923,10 +923,10 @@ impl Page { } } - fn extra_height(&self, device: &dyn Device, bb: &Rect2, cell: &DrawCell) -> usize { + fn extra_height(&self, device: &dyn Device, bb: &Rect2, cell: &DrawCell) -> isize { use Axis2::*; - let height = device.measure_cell_height(cell, bb[X].len()); - usize::saturating_sub(bb[Y].len(), height) + let height = device.measure_cell_height(cell, bb[X].len() as isize); + bb[Y].len() as isize - height } fn draw_cell(&self, device: &mut dyn Device, ofs: Coord2, cell: &RenderCell) { let mut bb = Rect2::from_fn(|a| { @@ -980,8 +980,8 @@ struct Selection { b: Axis2, z0: usize, z1: usize, - p0: usize, - p1: usize, + p0: isize, + p1: isize, h: Index2, } @@ -1051,10 +1051,10 @@ struct Map { /// the right. That way each rule contributes to both the cell on its left and /// on its right.) fn distribute_spanned_width( - width: usize, - unspanned: &[usize], - spanned: &mut [usize], - rules: &[usize], + width: isize, + unspanned: &[isize], + spanned: &mut [isize], + rules: &[isize], ) { let n = unspanned.len(); if n == 0 { @@ -1064,15 +1064,15 @@ fn distribute_spanned_width( debug_assert_eq!(spanned.len(), n); debug_assert_eq!(rules.len(), n + 1); - let total_unspanned = unspanned.iter().sum::() + let total_unspanned = unspanned.iter().sum::() + rules .get(1..n) - .map_or(0, |rules| rules.iter().copied().sum::()); + .map_or(0, |rules| rules.iter().copied().sum::()); if total_unspanned >= width { return; } - let d0 = n; + let d0 = n as isize; let d1 = 2 * total_unspanned.max(1); let d = if total_unspanned > 0 { d0 * d1 * 2 @@ -1099,7 +1099,7 @@ fn distribute_spanned_width( /// Returns the width of the rule in `table` that is at offset `z` along axis /// `a`, if rendered on `device`. -fn measure_rule(device: &dyn Device, table: &Table, a: Axis2, z: usize) -> usize { +fn measure_rule(device: &dyn Device, table: &Table, a: Axis2, z: usize) -> isize { let b = !a; // Determine the types of rules that are present. @@ -1144,10 +1144,10 @@ struct Break { z: usize, /// Pixel offset within cell `z` (usually 0). - pixel: usize, + pixel: isize, /// Width of headers of `page` along `axis`. - hw: usize, + hw: isize, } impl Break { @@ -1169,7 +1169,7 @@ impl Break { /// Returns the width that would be required along this breaker's axis to /// render a page from the current position up to but not including `cell`. - fn needed_size(&self, cell: usize) -> usize { + fn needed_size(&self, cell: usize) -> isize { // Width of header not including its rightmost rule. let mut size = self .page @@ -1212,7 +1212,7 @@ impl Break { /// completely broken up, or if `size` is too small to reasonably render any /// cells. The latter will never happen if `size` is at least as large as /// the page size passed to [Page::new] along the axis using for breaking. - fn next(&mut self, device: &dyn Device, size: usize) -> Option> { + fn next(&mut self, device: &dyn Device, size: isize) -> Option> { if !self.has_next() { return None; } @@ -1233,7 +1233,7 @@ impl Break { }) } - fn break_cell(&self, device: &dyn Device, z: usize, overflow: usize) -> usize { + fn break_cell(&self, device: &dyn Device, z: usize, overflow: isize) -> isize { if self.cell_is_breakable(device, z) { // If there is no right header and we render a partial cell // on the right side of the body, then we omit the rightmost @@ -1312,7 +1312,7 @@ impl Break { } } - fn find_breakpoint(&mut self, device: &dyn Device, size: usize) -> Option<(usize, usize)> { + fn find_breakpoint(&mut self, device: &dyn Device, size: isize) -> Option<(usize, isize)> { for z in self.z..self.page.n[self.axis] { let needed = self.needed_size(z + 1); if needed > size { @@ -1406,7 +1406,7 @@ impl Pager { let total_height = pages .iter() .map(|page: &Arc| page.total_size(Axis2::Y)) - .sum::() as f64; + .sum::() as f64; let max_height = device.params().size[Axis2::Y] as f64; if total_height * scale >= max_height { scale *= max_height / total_height; @@ -1434,7 +1434,7 @@ impl Pager { .and_then(|x_break| { x_break.next( device, - (device.params().size[Axis2::X] as f64 / self.scale) as usize, + (device.params().size[Axis2::X] as f64 / self.scale) as isize, ) }) .map(|page| Break::new(page, Axis2::Y)); @@ -1453,12 +1453,12 @@ impl Pager { /// Returns the amount of vertical space actually used by the rendered /// chunk, which will be 0 if `space` is too small to render anything or if /// no content remains (use [Self::has_next] to distinguish these cases). - pub fn draw_next(&mut self, device: &mut dyn Device, mut space: usize) -> usize { + pub fn draw_next(&mut self, device: &mut dyn Device, mut space: isize) -> isize { use Axis2::*; if self.scale != 1.0 { device.scale(self.scale); - space = (space as f64 / self.scale) as usize; + space = (space as f64 / self.scale) as isize; } let mut ofs = Coord2::new(0, 0); @@ -1475,7 +1475,7 @@ impl Pager { } if self.scale != 1.0 { - ofs[Y] = (ofs[Y] as f64 * self.scale) as usize; + ofs[Y] = (ofs[Y] as f64 * self.scale) as isize; } ofs[Y] } diff --git a/rust/pspp/src/output/spv/legacy_xml.rs b/rust/pspp/src/output/spv/legacy_xml.rs index 1e218efcc3..c1523f5577 100644 --- a/rust/pspp/src/output/spv/legacy_xml.rs +++ b/rust/pspp/src/output/spv/legacy_xml.rs @@ -344,7 +344,7 @@ impl Visualization { && let Ok(max_width) = max_width.parse::() { look.heading_widths[HeadingRegion::Columns] = - min_width.as_pt_f64() as usize..=max_width.as_pt_f64() as usize; + min_width.as_pt_f64() as isize..=max_width.as_pt_f64() as isize; } } diff --git a/rust/pspp/src/output/spv/light.rs b/rust/pspp/src/output/spv/light.rs index d2f26966d0..7b120d5448 100644 --- a/rust/pspp/src/output/spv/light.rs +++ b/rust/pspp/src/output/spv/light.rs @@ -86,8 +86,8 @@ impl LightTable { LabelPosition::Nested }, heading_widths: enum_map! { - HeadingRegion::Rows => self.header.min_row_heading_width as usize..=self.header.max_row_heading_width as usize, - HeadingRegion::Columns => self.header.min_column_heading_width as usize..=self.header.max_column_heading_width as usize, + HeadingRegion::Rows => self.header.min_row_heading_width as isize..=self.header.max_row_heading_width as isize, + HeadingRegion::Columns => self.header.min_column_heading_width as isize..=self.header.max_column_heading_width as isize, }, footnote_marker_type: if self.table_settings.show_alphabetic_markers { FootnoteMarkerType::Alphabetic