rxing/oned/one_d_code_writer.rs
1/*
2 * Copyright 2011 ZXing authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17use crate::{
18 common::{BitMatrix, Result},
19 BarcodeFormat, EncodeHints, Exceptions, Writer,
20};
21
22/**
23 * <p>Encapsulates functionality and implementation that is common to one-dimensional barcodes.</p>
24 *
25 * @author dsbnatut@gmail.com (Kazuki Nishiura)
26 */
27pub trait OneDimensionalCodeWriter: Writer {
28 // private static final Pattern NUMERIC = Pattern.compile("[0-9]+");
29
30 /**
31 * Encode the contents to boolean array expression of one-dimensional barcode.
32 * Start code and end code should be included in result, and side margins should not be included.
33 *
34 * @param contents barcode contents to encode
35 * @return a {@code boolean[]} of horizontal pixels (false = white, true = black)
36 */
37 fn encode_oned(&self, contents: &str) -> Result<Vec<bool>>;
38
39 /**
40 * Can be overwritten if the encode requires to read the hints map. Otherwise it defaults to {@code encode}.
41 * @param contents barcode contents to encode
42 * @param hints encoding hints
43 * @return a {@code boolean[]} of horizontal pixels (false = white, true = black)
44 */
45 fn encode_oned_with_hints(&self, contents: &str, _hints: &EncodeHints) -> Result<Vec<bool>> {
46 self.encode_oned(contents)
47 }
48
49 fn getSupportedWriteFormats(&self) -> Option<Vec<BarcodeFormat>> {
50 None
51 }
52
53 /**
54 * @return a byte array of horizontal pixels (0 = white, 1 = black)
55 */
56 fn renderRXingResult(
57 code: &[bool],
58 width: i32,
59 height: i32,
60 sidesMargin: u32,
61 ) -> Result<BitMatrix> {
62 let inputWidth = code.len();
63 // Add quiet zone on both sides.
64 let fullWidth = inputWidth + sidesMargin as usize;
65 let outputWidth = width.max(fullWidth as i32);
66 let outputHeight = 1.max(height);
67
68 let multiple = outputWidth as usize / fullWidth;
69 let leftPadding = (outputWidth as isize - (inputWidth as isize * multiple as isize)) / 2;
70
71 let mut output = BitMatrix::new(outputWidth as u32, outputHeight as u32)?;
72
73 let mut inputX = 0;
74 let mut outputX = leftPadding;
75
76 while inputX < inputWidth {
77 if code[inputX] {
78 output.setRegion(outputX as u32, 0, multiple as u32, outputHeight as u32)?;
79 }
80
81 inputX += 1;
82 outputX += multiple as isize;
83 }
84 Ok(output)
85 }
86
87 /**
88 * @param contents string to check for numeric characters
89 * @throws IllegalArgumentException if input contains characters other than digits 0-9.
90 */
91 fn checkNumeric(contents: &str) -> Result<()> {
92 let is_numeric = contents.chars().all(|c| c.is_numeric());
93 if !is_numeric {
94 Err(Exceptions::illegal_argument_with(
95 "Input should only contain digits 0-9",
96 ))
97 } else {
98 Ok(())
99 }
100 }
101
102 /**
103 * @param target encode black/white pattern into this array
104 * @param pos position to start encoding at in {@code target}
105 * @param pattern lengths of black/white runs to encode
106 * @param startColor starting color - false for white, true for black
107 * @return the number of elements added to target.
108 */
109 fn appendPattern<T: TryInto<usize> + Copy>(
110 target: &mut [bool],
111 pos: usize,
112 pattern: &[T],
113 startColor: bool,
114 ) -> u32 {
115 let mut color = startColor;
116 let mut numAdded = 0;
117 let mut pos = pos;
118 for len in pattern {
119 for _j in 0..TryInto::<usize>::try_into(*len).unwrap_or_default() {
120 target[pos] = color;
121 pos += 1;
122 }
123 numAdded += TryInto::<usize>::try_into(*len).unwrap_or_default();
124 color = !color; // flip color after each segment
125 }
126 numAdded as u32
127 }
128
129 fn getDefaultMargin(&self) -> u32 {
130 // CodaBar spec requires a side margin to be more than ten times wider than narrow space.
131 // This seems like a decent idea for a default for all formats.
132 10
133 }
134}