ltk_webkit/wpe/print/
sheet.rsuse image::{ imageops, Rgb, RgbImage };
use super::geometry::Geometry;
use super::pdf;
pub( super ) fn sheet( rgba: &[ u8 ], width: u32, first: u32, rows: u32, height: u32, geometry: &Geometry, out_width: u32 ) -> Result<( Vec<u8>, u32, u32 ), String>
{
if width == 0 || height == 0 || out_width == 0 { return Err( "empty page".to_string() ); }
let area = RgbImage::from_raw( width, height, pdf::flatten( rgba, width, first, rows, height ) ).ok_or( "the page does not fit its size" )?;
let ( paper_width, paper_height ) = geometry.paper;
let ( left, bottom, area_w, area_h ) = geometry.area;
let px = out_width as f64 / paper_width;
let sheet_h = ( paper_height * px ).round().max( 1.0 ) as u32;
let scaled = imageops::resize( &area, ( area_w * px ).round().max( 1.0 ) as u32, ( area_h * px ).round().max( 1.0 ) as u32, imageops::FilterType::Triangle );
let mut out = RgbImage::from_pixel( out_width, sheet_h, Rgb( [ 255; 3 ] ) );
let top = paper_height - bottom - area_h;
imageops::replace( &mut out, &scaled, ( left * px ).round() as i64, ( top * px ).round() as i64 );
let rgba = out.pixels().flat_map( |p| [ p[ 0 ], p[ 1 ], p[ 2 ], 255 ] ).collect();
Ok( ( rgba, out_width, sheet_h ) )
}
#[ cfg( test ) ]
mod tests
{
use super::*;
use crate::types::PrintSettings;
#[ test ]
fn the_margins_are_white_and_the_page_is_inside()
{
let g = super::super::geometry::geometry( &PrintSettings::default(), 1.0, 72.0 ).unwrap();
let ( w, h ) = ( 100u32, 140u32 );
let black = [ 0u8, 0, 0, 255 ].repeat( ( w * h ) as usize );
let ( rgba, width, height ) = sheet( &black, w, 0, h, h, &g, 300 ).unwrap();
assert_eq!( width, 300 );
assert_eq!( height, ( 300.0 * g.paper.1 / g.paper.0 ).round() as u32 );
let at = |x: u32, y: u32| rgba[ ( ( y * width + x ) * 4 ) as usize ];
assert_eq!( at( 2, 2 ), 255 );
assert_eq!( at( width / 2, height / 2 ), 0 );
}
}