1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
//! Scanlines
//use std::collections::HashMap;
/// Contigious area of data
#[derive(Debug,Default)]
pub(crate) struct Span {
/// Starting x position
pub x: i64,
/// Length of span
pub len: i64,
/// Cover values with len values
pub covers: Vec<u64>,
}
/// Unpacked Scanline
///
/// Represents a single row of an image
#[derive(Debug,Default)]
pub(crate) struct ScanlineU8 {
/// Last x value used
///
/// Used as a state variable
last_x: i64,
/// Minimum x position
///
/// This value can probably be removed
min_x: i64,
/// Collection of spans
pub spans: Vec<Span>,
// / Collection of covers
// / Needed ?
//covers: HashMap<i64, u64>,
/// Current y value
///
/// State variable
pub y: i64,
}
const LAST_X: i64 = 0x7FFF_FFF0;
impl ScanlineU8 {
/// Create a new empty scanline
pub fn new() -> Self {
Self { last_x: LAST_X, min_x: 0, y: 0,
spans: vec![], } //covers: HashMap::new() }
}
/// Reset values and clear spans
pub fn reset_spans(&mut self) {
self.last_x = LAST_X;
self.spans.clear();
//self.covers.clear();
}
/// Reset values and clear spans, setting min value
pub fn reset(&mut self, min_x: i64, _max_x: i64) {
self.last_x = LAST_X;
self.min_x = min_x;
self.spans = vec![];
//self.covers = HashMap::new()
}
/// Set the current row (y) that is to be worked on
pub fn finalize(&mut self, y: i64) {
self.y = y;
}
/// Total number of spans
pub fn num_spans(&self) -> usize {
self.spans.len()
}
/// Add a span starting at x, with a length and cover value
///
/// If the x value is 1 greater than the last value, the length of that
/// span is increased and the cover value appended
/// Otherwise, not a new span is created
pub fn add_span(&mut self, x: i64, len: i64, cover: u64) {
let x = x - self.min_x;
//self.covers.insert( x, cover );
if x == self.last_x + 1 {
let cur = self.spans.last_mut().unwrap();
//eprintln!("ADD_SPAN: Increasing length of span: {} {} x: {} {}", cur.len, cur.covers.len(), x+self.min_x, len);
cur.len += len;
cur.covers.extend(vec![cover; len as usize]);
//eprintln!("ADD_SPAN: Increasing length of span: {} {} x: {}", cur.len, cur.covers.len(), x+self.min_x);
} else {
//eprintln!("ADD_SPAN: Adding span of length: {} at {}", len, x+self.min_x);
let span = Span { x: x + self.min_x, len,
covers: vec![cover; len as usize] };
self.spans.push(span);
}
self.last_x = x + len - 1;
}
/// Add a single length span, cell, with a cover value
///
/// If the cell is 1 beyond the last value, the length is increased and the
/// cover is append, otherwise a new span is created
pub fn add_cell(&mut self, x: i64, cover: u64) {
let x = x - self.min_x;
//self.covers.insert( x, cover );
if x == self.last_x + 1 {
let cur = self.spans.last_mut().unwrap();
cur.len += 1;
cur.covers.push(cover);
} else {
//let cover = self.covers.get(&x).unwrap().clone();
let span = Span { x: x + self.min_x, len: 1,
covers: vec![cover] };
self.spans.push(span);
}
self.last_x = x;
}
}