5f7b32caa4338ee1bdc837f5b5d7a4759882e183
[pdfium.git] / xfa / src / fxbarcode / oned / BC_OnedCode128Writer.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4 \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 // Original code is licensed as follows:\r
7 /*\r
8  * Copyright 2010 ZXing authors\r
9  *\r
10  * Licensed under the Apache License, Version 2.0 (the "License");\r
11  * you may not use this file except in compliance with the License.\r
12  * You may obtain a copy of the License at\r
13  *\r
14  *      http://www.apache.org/licenses/LICENSE-2.0\r
15  *\r
16  * Unless required by applicable law or agreed to in writing, software\r
17  * distributed under the License is distributed on an "AS IS" BASIS,\r
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
19  * See the License for the specific language governing permissions and\r
20  * limitations under the License.\r
21  */\r
22 \r
23 #include "../barcode.h"\r
24 #include "../BC_Writer.h"\r
25 #include "../BC_Reader.h"\r
26 #include "BC_OneDReader.h"\r
27 #include "BC_OneDimWriter.h"\r
28 #include "BC_OnedCode128Reader.h"\r
29 #include "BC_OnedCode128Writer.h"\r
30 const int32_t CBC_OnedCode128Writer::CODE_CODE_B = 100;\r
31 const int32_t CBC_OnedCode128Writer::CODE_CODE_C = 99;\r
32 const int32_t CBC_OnedCode128Writer::CODE_START_B = 104;\r
33 const int32_t CBC_OnedCode128Writer::CODE_START_C = 105;\r
34 const int32_t CBC_OnedCode128Writer::CODE_STOP = 106;\r
35 CBC_OnedCode128Writer::CBC_OnedCode128Writer()\r
36 {\r
37     m_codeFormat = BC_CODE128_B;\r
38 }\r
39 CBC_OnedCode128Writer::CBC_OnedCode128Writer(BC_TYPE type)\r
40 {\r
41     m_codeFormat = type;\r
42 }\r
43 CBC_OnedCode128Writer::~CBC_OnedCode128Writer()\r
44 {\r
45 }\r
46 BC_TYPE CBC_OnedCode128Writer::GetType()\r
47 {\r
48     return m_codeFormat;\r
49 }\r
50 FX_BOOL CBC_OnedCode128Writer::CheckContentValidity(FX_WSTR contents)\r
51 {\r
52     FX_BOOL ret = TRUE;\r
53     int32_t position = 0;\r
54     int32_t patternIndex = -1;\r
55     if (m_codeFormat == BC_CODE128_B || m_codeFormat == BC_CODE128_C) {\r
56         while (position < contents.GetLength()) {\r
57             patternIndex = (int32_t)contents.GetAt(position);\r
58             if (patternIndex >= 32 && patternIndex <= 126 && patternIndex != 34) {\r
59                 position++;\r
60                 continue;\r
61             } else {\r
62                 ret = FALSE;\r
63                 break;\r
64             }\r
65             position ++;\r
66         }\r
67     } else {\r
68         ret = FALSE;\r
69     }\r
70     return ret;\r
71 }\r
72 CFX_WideString CBC_OnedCode128Writer::FilterContents(FX_WSTR contents)\r
73 {\r
74     CFX_WideString filterChineseChar;\r
75     FX_WCHAR ch;\r
76     for (int32_t i = 0; i < contents.GetLength(); i++) {\r
77         ch = contents.GetAt(i);\r
78         if(ch > 175) {\r
79             i++;\r
80             continue;\r
81         }\r
82         filterChineseChar += ch;\r
83     }\r
84     CFX_WideString filtercontents;\r
85     if (m_codeFormat == BC_CODE128_B) {\r
86         for (int32_t i = 0; i < filterChineseChar.GetLength(); i++) {\r
87             ch = filterChineseChar.GetAt(i);\r
88             if (ch >= 32 && ch <= 126) {\r
89                 filtercontents += ch;\r
90             } else {\r
91                 continue;\r
92             }\r
93         }\r
94     } else if (m_codeFormat == BC_CODE128_C) {\r
95         for (int32_t i = 0; i < filterChineseChar.GetLength(); i++) {\r
96             ch = filterChineseChar.GetAt(i);\r
97             if (ch >= 32 && ch <= 106) {\r
98                 filtercontents += ch;\r
99             } else {\r
100                 continue;\r
101             }\r
102         }\r
103     } else {\r
104         filtercontents = contents;\r
105     }\r
106     return filtercontents;\r
107 }\r
108 FX_BOOL CBC_OnedCode128Writer::SetTextLocation(BC_TEXT_LOC location)\r
109 {\r
110     if ( location < BC_TEXT_LOC_NONE || location > BC_TEXT_LOC_BELOWEMBED) {\r
111         return FALSE;\r
112     }\r
113     m_locTextLoc = location;\r
114     return TRUE;\r
115 }\r
116 uint8_t *CBC_OnedCode128Writer::Encode(const CFX_ByteString &contents, BCFORMAT format, int32_t &outWidth, int32_t &outHeight, int32_t hints, int32_t &e)\r
117 {\r
118     if(format != BCFORMAT_CODE_128) {\r
119         e = BCExceptionOnlyEncodeCODE_128;\r
120         return NULL;\r
121     }\r
122     uint8_t *ret = CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e);\r
123     BC_EXCEPTION_CHECK_ReturnValue(e, NULL);\r
124     return ret;\r
125 }\r
126 uint8_t *CBC_OnedCode128Writer::Encode(const CFX_ByteString &contents, BCFORMAT format, int32_t &outWidth, int32_t &outHeight, int32_t &e)\r
127 {\r
128     uint8_t *ret =  Encode(contents, format, outWidth, outHeight, 0, e);\r
129     BC_EXCEPTION_CHECK_ReturnValue(e, NULL);\r
130     return ret;\r
131 }\r
132 FX_BOOL CBC_OnedCode128Writer::IsDigits(const CFX_ByteString &contents, int32_t start, int32_t length)\r
133 {\r
134     int32_t end = start + length;\r
135     for (int32_t i = start; i < end; i++) {\r
136         if (contents[i] < '0' || contents[i] > '9') {\r
137             return FALSE;\r
138         }\r
139     }\r
140     return TRUE;\r
141 }\r
142 uint8_t *CBC_OnedCode128Writer::Encode(const CFX_ByteString &contents, int32_t &outLength, int32_t &e)\r
143 {\r
144     int32_t length = contents.GetLength();\r
145     if(contents.GetLength() < 1 || contents.GetLength() > 80) {\r
146         e = BCExceptionContentsLengthShouldBetween1and80;\r
147         return NULL;\r
148     }\r
149     CFX_PtrArray patterns;\r
150     int32_t checkSum = 0;\r
151     if (m_codeFormat == BC_CODE128_B) {\r
152         checkSum = Encode128B(contents, patterns);\r
153     } else if (m_codeFormat == BC_CODE128_C)    {\r
154         checkSum = Encode128C(contents, patterns);\r
155     } else {\r
156         e = BCExceptionFormatException;\r
157         return NULL;\r
158     }\r
159     checkSum %= 103;\r
160     patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[checkSum]);\r
161     patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[CODE_STOP]);\r
162     m_iContentLen = contents.GetLength() + 3;\r
163     int32_t codeWidth = 0;\r
164     for(int32_t k = 0; k < patterns.GetSize(); k++) {\r
165         int32_t *pattern = (int32_t*)patterns[k];\r
166         for(int32_t j = 0; j < 7; j++) {\r
167             codeWidth += pattern[j];\r
168         }\r
169     }\r
170     outLength = codeWidth;\r
171     uint8_t *result = FX_Alloc(uint8_t, outLength);\r
172     int32_t pos = 0;\r
173     for(int32_t j = 0; j < patterns.GetSize(); j++) {\r
174         int32_t* pattern = (int32_t*)patterns[j];\r
175         pos += AppendPattern(result, pos, pattern, 7, 1, e);\r
176         if (e != BCExceptionNO) {\r
177             FX_Free (result);\r
178             return NULL;\r
179         }\r
180     }\r
181     return result;\r
182 }\r
183 int32_t CBC_OnedCode128Writer::Encode128B(const CFX_ByteString &contents,  CFX_PtrArray &patterns)\r
184 {\r
185     int32_t checkSum = 0;\r
186     int32_t checkWeight = 1;\r
187     int32_t position = 0;\r
188     patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[CODE_START_B]);\r
189     checkSum += CODE_START_B * checkWeight;\r
190     while (position < contents.GetLength()) {\r
191         int32_t patternIndex = 0;\r
192         patternIndex = contents[position] - ' ';\r
193         position += 1;\r
194         patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[patternIndex]);\r
195         checkSum += patternIndex * checkWeight;\r
196         if (position != 0) {\r
197             checkWeight++;\r
198         }\r
199     }\r
200     return checkSum;\r
201 }\r
202 int32_t CBC_OnedCode128Writer::Encode128C(const CFX_ByteString &contents,  CFX_PtrArray &patterns)\r
203 {\r
204     int32_t checkSum = 0;\r
205     int32_t checkWeight = 1;\r
206     int32_t position = 0;\r
207     patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[CODE_START_C]);\r
208     checkSum += CODE_START_C * checkWeight;\r
209     while (position < contents.GetLength()) {\r
210         int32_t patternIndex = 0;\r
211         FX_CHAR ch = contents.GetAt(position);\r
212         if (ch < '0' || ch > '9') {\r
213             patternIndex = (int32_t)ch;\r
214             position++;\r
215         } else {\r
216             patternIndex = FXSYS_atoi(contents.Mid(position, 2));\r
217             if (contents.GetAt(position + 1) < '0' || contents.GetAt(position + 1) > '9') {\r
218                 position += 1;\r
219             } else {\r
220                 position += 2;\r
221             }\r
222         }\r
223         patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[patternIndex]);\r
224         checkSum += patternIndex * checkWeight;\r
225         if (position != 0) {\r
226             checkWeight++;\r
227         }\r
228     }\r
229     return checkSum;\r
230 }\r