1// Copyright 2017 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <cstring>
6
7#include "fxbarcode/oned/BC_OnedCode39Writer.h"
8#include "testing/gtest/include/gtest/gtest.h"
9
10namespace {
11
12// 3 wide and 6 narrow modules per char. 1 space between chars.
13const int MODULES_PER_CHAR = 3 * 3 + 6 * 1 + 1;
14
15// '*' is added as the first and last char.
16const int DELIMITER_CHARS = 2;
17
18// Last char may serve as checksum.
19const int CHECKSUM_CHARS = 1;
20
21TEST(OnedCode39WriterTest, SetWideNarrowRatio) {
22  // Code 39 barcodes encode strings of any size into modules in a
23  // unidimensional disposition.
24  // Each module is either: a narrow bar, a narrow space, a wide
25  // bar, or a wide space. Accepted wide-to-narrow ratios are between 2 and 3.
26  // This writer in particular only takes integer ratios, so it's either 2 or 3.
27  CBC_OnedCode39Writer writer;
28  EXPECT_FALSE(writer.SetWideNarrowRatio(0));
29  EXPECT_FALSE(writer.SetWideNarrowRatio(1));
30  EXPECT_TRUE(writer.SetWideNarrowRatio(2));
31  EXPECT_TRUE(writer.SetWideNarrowRatio(3));
32  EXPECT_FALSE(writer.SetWideNarrowRatio(4));
33  EXPECT_FALSE(writer.SetWideNarrowRatio(100));
34
35  writer.SetWideNarrowRatio(3);
36
37  int32_t width;
38  int32_t height;
39  uint8_t* encoded;
40  const char* expected;
41
42  encoded = writer.Encode("PDFIUM", BCFORMAT_CODE_39, width, height);
43  expected =
44      "#   # ### ### # "  // * Start
45      "# ### ### #   # "  // P
46      "# # ###   # ### "  // D
47      "# ### ###   # # "  // F
48      "# ### #   ### # "  // I
49      "###   # # # ### "  // U
50      "### ### # #   # "  // M
51      "#   # ### ### #";  // * End
52  FX_Free(encoded);
53
54  writer.SetWideNarrowRatio(2);
55
56  encoded = writer.Encode("PDFIUM", BCFORMAT_CODE_39, width, height);
57  expected =
58      "#  # ## ## # "  // * Start
59      "# ## ## #  # "  // P
60      "# # ##  # ## "  // D
61      "# ## ##  # # "  // F
62      "# ## #  ## # "  // I
63      "##  # # # ## "  // U
64      "## ## # #  # "  // M
65      "#  # ## ## #";  // * End
66  FX_Free(encoded);
67}
68
69TEST(OnedCode39WriterTest, Encode) {
70  CBC_OnedCode39Writer writer;
71  int32_t width;
72  int32_t height;
73  uint8_t* encoded;
74  const char* expected;
75
76  encoded = writer.Encode("", BCFORMAT_CODE_39, width, height);
77  EXPECT_EQ(1, height);
78  EXPECT_EQ((0 + DELIMITER_CHARS) * MODULES_PER_CHAR - 1, width);
79  expected =
80      "#   # ### ### # "  // * Start
81      "#   # ### ### #";  // * End
82  for (size_t i = 0; i < strlen(expected); i++) {
83    EXPECT_EQ(expected[i] != ' ', !!encoded[i]) << i;
84  }
85  FX_Free(encoded);
86
87  encoded = writer.Encode("123", BCFORMAT_CODE_39, width, height);
88  EXPECT_EQ(1, height);
89  EXPECT_EQ((3 + DELIMITER_CHARS) * MODULES_PER_CHAR - 1, width);
90  expected =
91      "#   # ### ### # "  // * Start
92      "### #   # # ### "  // 1
93      "# ###   # # ### "  // 2
94      "### ###   # # # "  // 3
95      "#   # ### ### #";  // * End
96  for (size_t i = 0; i < strlen(expected); i++) {
97    EXPECT_EQ(expected[i] != ' ', !!encoded[i]) << i;
98  }
99  FX_Free(encoded);
100
101  encoded = writer.Encode("PDFIUM", BCFORMAT_CODE_39, width, height);
102  EXPECT_EQ(1, height);
103  EXPECT_EQ((6 + DELIMITER_CHARS) * MODULES_PER_CHAR - 1, width);
104  expected =
105      "#   # ### ### # "  // * Start
106      "# ### ### #   # "  // P
107      "# # ###   # ### "  // D
108      "# ### ###   # # "  // F
109      "# ### #   ### # "  // I
110      "###   # # # ### "  // U
111      "### ### # #   # "  // M
112      "#   # ### ### #";  // * End
113  for (size_t i = 0; i < strlen(expected); i++) {
114    EXPECT_EQ(expected[i] != ' ', !!encoded[i]) << i;
115  }
116  FX_Free(encoded);
117
118  encoded = writer.Encode("A -$%./+Z", BCFORMAT_CODE_39, width, height);
119  EXPECT_EQ(1, height);
120  EXPECT_EQ((9 + DELIMITER_CHARS) * MODULES_PER_CHAR - 1, width);
121  expected =
122      "#   # ### ### # "  // * Start
123      "### # #   # ### "  // A
124      "#   ### # ### # "  // Space
125      "#   # # ### ### "  // -
126      "#   #   #   # # "  // $
127      "# #   #   #   # "  // %
128      "###   # # ### # "  // .
129      "#   #   # #   # "  // /
130      "#   # #   #   # "  // +
131      "#   ### ### # # "  // Z
132      "#   # ### ### #";  // * End
133  for (size_t i = 0; i < strlen(expected); i++) {
134    EXPECT_EQ(expected[i] != ' ', !!encoded[i]) << i;
135  }
136  FX_Free(encoded);
137}
138
139TEST(OnedCode39WriterTest, Checksum) {
140  CBC_OnedCode39Writer writer;
141  int32_t width;
142  int32_t height;
143  uint8_t* encoded;
144  const char* expected;
145
146  writer.SetCalcChecksum(true);
147
148  encoded = writer.Encode("123", BCFORMAT_CODE_39, width, height);
149  EXPECT_EQ(1, height);
150  EXPECT_EQ((3 + CHECKSUM_CHARS + DELIMITER_CHARS) * MODULES_PER_CHAR - 1,
151            width);
152  expected =
153      "#   # ### ### # "  // * Start
154      "### #   # # ### "  // 1 (1)
155      "# ###   # # ### "  // 2 (2)
156      "### ###   # # # "  // 3 (3)
157      "# ###   ### # # "  // 6 (6 = (1 + 2 + 3) % 43)
158      "#   # ### ### #";  // * End
159  for (size_t i = 0; i < strlen(expected); i++) {
160    EXPECT_EQ(expected[i] != ' ', !!encoded[i]) << i;
161  }
162  FX_Free(encoded);
163
164  encoded = writer.Encode("PDFIUM", BCFORMAT_CODE_39, width, height);
165  EXPECT_EQ(1, height);
166  EXPECT_EQ((6 + CHECKSUM_CHARS + DELIMITER_CHARS) * MODULES_PER_CHAR - 1,
167            width);
168  expected =
169      "#   # ### ### # "  // * Start
170      "# ### ### #   # "  // P (25)
171      "# # ###   # ### "  // D (13)
172      "# ### ###   # # "  // F (15)
173      "# ### #   ### # "  // I (18)
174      "###   # # # ### "  // U (30)
175      "### ### # #   # "  // M (22)
176      "###   # # ### # "  // . (37 = (25 + 13 + 15 + 18 + 30 + 22) % 43)
177      "#   # ### ### #";  // * End
178  for (size_t i = 0; i < strlen(expected); i++) {
179    EXPECT_EQ(expected[i] != ' ', !!encoded[i]) << i;
180  }
181  FX_Free(encoded);
182}
183
184}  // namespace
185