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}