From c52cad386671c4c0122a49bd3a41d7808a6718c6 Mon Sep 17 00:00:00 2001 From: starovoid Date: Sat, 28 Sep 2024 12:02:20 +0300 Subject: [PATCH] PDF417 encoding method with sizing --- src/pdf417/encoder/barcode_matrix.rs | 16 ++++-- src/pdf417/encoder/barcode_row.rs | 4 ++ src/pdf417/pdf_417_writer.rs | 84 ++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 4 deletions(-) diff --git a/src/pdf417/encoder/barcode_matrix.rs b/src/pdf417/encoder/barcode_matrix.rs index 28e4d36..4edcf9c 100644 --- a/src/pdf417/encoder/barcode_matrix.rs +++ b/src/pdf417/encoder/barcode_matrix.rs @@ -22,10 +22,10 @@ use super::BarcodeRow; * @author Jacob Haynes */ pub struct BarcodeMatrix { - matrix: Vec, - currentRow: isize, - height: usize, - width: usize, + pub matrix: Vec, + pub currentRow: isize, + pub height: usize, + pub width: usize, } impl BarcodeMatrix { /** @@ -81,4 +81,12 @@ impl BarcodeMatrix { matrixOut } + + pub fn getHeight(&self) -> usize { + self.matrix.len() + } + + pub fn getWidth(&self) -> usize { + self.matrix[0].len() + } } diff --git a/src/pdf417/encoder/barcode_row.rs b/src/pdf417/encoder/barcode_row.rs index 6f30372..6514a21 100644 --- a/src/pdf417/encoder/barcode_row.rs +++ b/src/pdf417/encoder/barcode_row.rs @@ -70,4 +70,8 @@ impl BarcodeRow { output } + + pub fn len(&self) -> usize { + self.row.len() + } } diff --git a/src/pdf417/pdf_417_writer.rs b/src/pdf417/pdf_417_writer.rs index b10a4a5..d4a64e4 100644 --- a/src/pdf417/pdf_417_writer.rs +++ b/src/pdf417/pdf_417_writer.rs @@ -132,6 +132,90 @@ impl Writer for PDF417Writer { } impl PDF417Writer { + /// Encode with hints focusing on height and width. + pub fn encode_sized_with_hints( + &self, + contents: &str, + format: &crate::BarcodeFormat, + width: i32, + height: i32, + hints: &crate::EncodingHintDictionary, + ) -> Result { + if format != &BarcodeFormat::PDF_417 { + return Err(Exceptions::illegal_argument_with(format!( + "Can only encode PDF_417, but got {format}" + ))); + } + + let mut encoder = PDF417::new(); + let mut margin = WHITE_SPACE; + let mut errorCorrectionLevel = DEFAULT_ERROR_CORRECTION_LEVEL; + let mut autoECI = false; + + if !hints.is_empty() { + if let Some(EncodeHintValue::Pdf417Compact(compact)) = + hints.get(&EncodeHintType::PDF417_COMPACT) + { + if let Ok(res) = compact.parse::() { + encoder.setCompact(res); + } + } + if let Some(EncodeHintValue::Pdf417Compaction(compaction)) = + hints.get(&EncodeHintType::PDF417_COMPACTION) + { + encoder.setCompaction(compaction.try_into()?); + } + if let Some(EncodeHintValue::Pdf417Dimensions(dimensions)) = + hints.get(&EncodeHintType::PDF417_DIMENSIONS) + { + encoder.setDimensions( + dimensions.getMaxCols() as u32, + dimensions.getMinCols() as u32, + dimensions.getMaxRows() as u32, + dimensions.getMinRows() as u32, + ); + } + if let Some(EncodeHintValue::Margin(m1)) = hints.get(&EncodeHintType::MARGIN) { + if let Ok(m) = m1.parse::() { + margin = m; + } + } + if let Some(EncodeHintValue::ErrorCorrection(ec)) = + hints.get(&EncodeHintType::ERROR_CORRECTION) + { + if let Ok(ec_parsed) = ec.parse::() { + errorCorrectionLevel = ec_parsed; + } + } + if let Some(EncodeHintValue::CharacterSet(cs)) = + hints.get(&EncodeHintType::CHARACTER_SET) + { + encoder.setEncoding(CharacterSet::get_character_set_by_name(cs)); + } + if let Some(EncodeHintValue::Pdf417AutoEci(auto_eci_str)) = + hints.get(&EncodeHintType::PDF417_AUTO_ECI) + { + if let Ok(auto_eci_parsed) = auto_eci_str.parse::() { + autoECI = auto_eci_parsed; + } + } + } + + encoder.generateBarcodeLogicWithAutoECI(contents, errorCorrectionLevel, autoECI)?; + + let logicalMatrix = encoder + .getBarcodeMatrix() + .as_ref() + .ok_or(Exceptions::ILLEGAL_STATE)?; + + let scaleX = (width as f64) / (logicalMatrix.getWidth() as f64); + let scaleY = (height as f64) / (logicalMatrix.getHeight() as f64); + + let originalScale = logicalMatrix.getScaledMatrix(scaleX.round() as usize, scaleY as usize); + + Self::bitMatrixFromBitArray(&originalScale, margin).ok_or(Exceptions::ILLEGAL_STATE) + } + /** * Takes encoder, accounts for width/height, and retrieves bit matrix */