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
}
impl CairoDriver {
pub fn new(config: &CairoConfig) -> cairo::Result<Self> {
- 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;
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)]
pub size: Coord2,
/// Minimum cell size to allow breaking.
- pub min_break: EnumMap<Axis2, usize>,
+ pub min_break: EnumMap<Axis2, isize>,
/// The basic font.
pub font: FontDescription,
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":
///
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! {
}
}
- 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();
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!()
};
}
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);
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::<i32>().max(0) as usize)
+fn margin(cell: &DrawCell, axis: Axis2) -> isize {
+ px_to_xr(cell.cell_style.margins[axis].iter().sum::<i32>() as isize)
}
pub fn parse_font_style(font_style: &FontStyle) -> FontDescription {
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
};
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.
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);
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),
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) {
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,
) {
self.params
}
- fn measure_cell_width(&self, cell: &DrawCell) -> EnumMap<Extreme, usize> {
- fn add_margins(cell: &DrawCell, width: usize) -> usize {
+ fn measure_cell_width(&self, cell: &DrawCell) -> EnumMap<Extreme, isize> {
+ fn add_margins(cell: &DrawCell, width: isize) -> isize {
if width > 0 {
width + margin(cell, Axis2::X)
} else {
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!()
}
&mut self,
draw_cell: &DrawCell,
mut bb: Rect2,
- valign_offset: usize,
- spill: EnumMap<Axis2, [usize; 2]>,
+ valign_offset: isize,
+ spill: EnumMap<Axis2, [isize; 2]>,
clip: &Rect2,
) {
let bg = draw_cell.font_style.bg;
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);
#[derive(Clone, Debug)]
pub struct CairoPageStyle {
- pub margins: EnumMap<Axis2, [usize; 2]>,
+ pub margins: EnumMap<Axis2, [isize; 2]>,
pub header: Document,
pub footer: Document,
pub initial_page_number: i32,
item: Option<Arc<Item>>,
context: Option<Context>,
fsm: Option<CairoFsm>,
- y: usize,
- y_max: usize,
+ y: isize,
+ y_max: isize,
}
impl CairoPager {
self.fsm = None;
} else if chunk == 0 {
assert!(self.y > 0);
- self.y = usize::MAX;
+ self.y = isize::MAX;
return;
}
}
heading: &'a Document,
fsm_style: &'a CairoFsmStyle,
page_number: i32,
- width: usize,
+ width: isize,
font_resolution: f64,
substitutions: F,
}
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);
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
emphasis: bool,
/// Page width.
- width: usize,
+ width: isize,
/// Minimum cell size to break across pages.
min_hbreak: usize,
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,
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,
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}")?;
}
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;
}
&self.params
}
- fn measure_cell_width(&self, cell: &DrawCell) -> EnumMap<Extreme, usize> {
+ fn measure_cell_width(&self, cell: &DrawCell) -> EnumMap<Extreme, isize> {
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!()
}
};
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());
}
}
&mut self,
cell: &DrawCell,
bb: Rect2,
- valign_offset: usize,
- _spill: EnumMap<Axis2, [usize; 2]>,
+ valign_offset: isize,
+ _spill: EnumMap<Axis2, [isize; 2]>,
clip: &Rect2,
) {
let display = cell.display();
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;
} else {
Cow::from(text)
};
- self.get_line(y).put(x, &text);
+ self.get_line(y as usize).put(x as usize, &text);
}
}
pub fn clip_text<'a>(
text: &'a str,
- bb: &Range<usize>,
- clip: &Range<usize>,
-) -> Option<(usize, &'a str)> {
+ bb: &Range<isize>,
+ clip: &Range<isize>,
+) -> 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 {
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;
+ }
}
}
}
pub row_label_position: LabelPosition,
/// Ranges of column widths in the two heading regions, in 1/96" units.
- pub heading_widths: EnumMap<HeadingRegion, RangeInclusive<usize>>,
+ pub heading_widths: EnumMap<HeadingRegion, RangeInclusive<isize>>,
/// Kind of markers to use for footnotes.
pub footnote_marker_type: FootnoteMarkerType,
/// A 2-dimensional `(x,y)` pair.
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
-pub struct Coord2(pub EnumMap<Axis2, usize>);
+pub struct Coord2(pub EnumMap<Axis2, isize>);
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,
})
}
- 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;
pub fn from_fn<F>(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<EnumMap<Axis2, usize>> for Coord2 {
- fn from(value: EnumMap<Axis2, usize>) -> Self {
+impl From<EnumMap<Axis2, isize>> for Coord2 {
+ fn from(value: EnumMap<Axis2, isize>) -> Self {
Self(value)
}
}
impl Index<Axis2> for Coord2 {
- type Output = usize;
+ type Output = isize;
fn index(&self, index: Axis2) -> &Self::Output {
&self.0[index]
}
#[derive(Clone, Debug, Default)]
-pub struct Rect2(pub EnumMap<Axis2, Range<usize>>);
+pub struct Rect2(pub EnumMap<Axis2, Range<isize>>);
impl Rect2 {
- pub fn new(x_range: Range<usize>, y_range: Range<usize>) -> Self {
+ pub fn new(x_range: Range<isize>, y_range: Range<isize>) -> Self {
Self(enum_map! {
Axis2::X => x_range.clone(),
Axis2::Y => y_range.clone(),
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<usize>), b_range: Range<usize>) -> Self {
+ pub fn for_ranges((a, a_range): (Axis2, Range<isize>), b_range: Range<isize>) -> Self {
let b = !a;
let mut ranges = EnumMap::default();
ranges[a] = a_range;
}
pub fn from_fn<F>(f: F) -> Self
where
- F: FnMut(Axis2) -> Range<usize>,
+ F: FnMut(Axis2) -> Range<isize>,
{
Self(EnumMap::from_fn(f))
}
}
}
-impl From<EnumMap<Axis2, Range<usize>>> for Rect2 {
- fn from(value: EnumMap<Axis2, Range<usize>>) -> Self {
+impl From<EnumMap<Axis2, Range<isize>>> for Rect2 {
+ fn from(value: EnumMap<Axis2, Range<isize>>) -> Self {
Self(value)
}
}
impl Index<Axis2> for Rect2 {
- type Output = Range<usize>;
+ type Output = Range<isize>;
fn index(&self, index: Axis2) -> &Self::Output {
&self.0[index]
}
/// 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()
}
}
/// 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()
}
/// 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<Axis2, usize>,
+ pub font_size: EnumMap<Axis2, isize>,
/// Width of different kinds of lines.
- pub line_widths: EnumMap<Stroke, usize>,
+ pub line_widths: EnumMap<Stroke, isize>,
/// 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<usize>,
+ pub px_size: Option<isize>,
/// 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<Axis2, usize>,
+ pub min_break: EnumMap<Axis2, isize>,
/// True if the driver supports cell margins. (If false, the rendering
/// engine will insert a small space betweeen adjacent cells that don't have
impl Params {
/// Returns a small but visible width.
- fn em(&self) -> usize {
+ fn em(&self) -> isize {
self.font_size[Axis2::X]
}
}
///
/// - `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<Extreme, usize>;
+ fn measure_cell_width(&self, cell: &DrawCell) -> EnumMap<Extreme, isize>;
/// 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,
///
/// 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`.
///
&mut self,
draw_cell: &DrawCell,
bb: Rect2,
- valign_offset: usize,
- spill: EnumMap<Axis2, [usize; 2]>,
+ valign_offset: isize,
+ spill: EnumMap<Axis2, [isize; 2]>,
clip: &Rect2,
);
///
/// Rules and columns can have width or height 0, in which case consecutive
/// values in this array are equal.
- cp: EnumMap<Axis2, Vec<usize>>,
+ cp: EnumMap<Axis2, Vec<isize>>,
/// [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
/// ```
/// Each entry maps from a cell that overflows to the space that has been
/// trimmed off the cell.
- overflows: HashMap<Index2, EnumMap<Axis2, [usize; 2]>>,
+ overflows: HashMap<Index2, EnumMap<Axis2, [isize; 2]>>,
/// 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
}
/// Returns the width of `extent` along `axis`.
-fn axis_width(cp: &[usize], extent: Range<usize>) -> usize {
+fn axis_width(cp: &[isize], extent: Range<usize>) -> isize {
cp[extent.end] - cp[extent.start]
}
/// Returns the width of cells within `extent` along `axis`.
-fn joined_width(cp: &[usize], extent: Range<usize>) -> usize {
+fn joined_width(cp: &[isize], extent: Range<usize>) -> 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`.
}
/// 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)
}
/// 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<Table>, device: &dyn Device, min_width: usize, look: &Look) -> Self {
+ fn new(table: Arc<Table>, device: &dyn Device, min_width: isize, look: &Look) -> Self {
use Axis2::*;
use Extreme::*;
}
// Decide final column widths.
- let rule_widths = rules[X].iter().copied().sum::<usize>();
- let table_widths = EnumMap::from_fn(|ext| columns[ext].iter().sum::<usize>() + rule_widths);
+ let rule_widths = rules[X].iter().copied().sum::<isize>();
+ let table_widths = EnumMap::from_fn(|ext| columns[ext].iter().sum::<isize>() + rule_widths);
let cp_x = if table_widths[Max] <= device.params().size[X] {
// Fits even with maximum widths. Use them.
}
}
- fn use_row_widths(rows: &[usize], rules: &[usize]) -> Vec<usize> {
+ fn use_row_widths(rows: &[isize], rules: &[isize]) -> Vec<isize> {
let mut vec = once(0)
.chain(interleave(rules, rows).copied())
.collect::<Vec<_>>();
}
fn interpolate_column_widths(
- target: usize,
- columns: &EnumMap<Extreme, Vec<usize>>,
- widths: &EnumMap<Extreme, usize>,
- rules: &[usize],
- ) -> Vec<usize> {
+ target: isize,
+ columns: &EnumMap<Extreme, Vec<isize>>,
+ widths: &EnumMap<Extreme, isize>,
+ rules: &[isize],
+ ) -> Vec<isize> {
use Extreme::*;
let avail = target - widths[Min];
}
/// Returns the width of `extent` along `axis`.
- fn axis_width(&self, axis: Axis2, extent: Range<usize>) -> usize {
+ fn axis_width(&self, axis: Axis2, extent: Range<usize>) -> 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>) -> usize {
+ fn joined_width(&self, axis: Axis2, extent: Range<usize>) -> 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)
}
}
/// 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()
}
self: &Arc<Self>,
a: Axis2,
extent: Range<usize>,
- pixel0: usize,
- pixel1: usize,
+ pixel0: isize,
+ pixel1: isize,
) -> Arc<Self> {
let b = !a;
let z0 = extent.start;
})
}
- fn total_size(&self, axis: Axis2) -> usize {
+ fn total_size(&self, axis: Axis2) -> isize {
self.cp[axis].last().copied().unwrap()
}
}
}
- 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| {
b: Axis2,
z0: usize,
z1: usize,
- p0: usize,
- p1: usize,
+ p0: isize,
+ p1: isize,
h: Index2,
}
/// 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 {
debug_assert_eq!(spanned.len(), n);
debug_assert_eq!(rules.len(), n + 1);
- let total_unspanned = unspanned.iter().sum::<usize>()
+ let total_unspanned = unspanned.iter().sum::<isize>()
+ rules
.get(1..n)
- .map_or(0, |rules| rules.iter().copied().sum::<usize>());
+ .map_or(0, |rules| rules.iter().copied().sum::<isize>());
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
/// 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.
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 {
/// 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
/// 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<Arc<Page>> {
+ fn next(&mut self, device: &dyn Device, size: isize) -> Option<Arc<Page>> {
if !self.has_next() {
return None;
}
})
}
- 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
}
}
- 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 {
let total_height = pages
.iter()
.map(|page: &Arc<Page>| page.total_size(Axis2::Y))
- .sum::<usize>() as f64;
+ .sum::<isize>() as f64;
let max_height = device.params().size[Axis2::Y] as f64;
if total_height * scale >= max_height {
scale *= max_height / total_height;
.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));
/// 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);
}
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]
}
&& let Ok(max_width) = max_width.parse::<Length>()
{
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;
}
}
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