1 // Copyright 2014 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 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 // Original code is licensed as follows:
7 /*
8 * Copyright 2009 ZXing authors
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 */
22
23 #include "xfa/src/fxbarcode/barcode.h"
24 #include "xfa/src/fxbarcode/BC_Writer.h"
25 #include "xfa/src/fxbarcode/BC_Reader.h"
26 #include "BC_OneDReader.h"
27 #include "BC_OneDimReader.h"
28 #include "BC_OneDimWriter.h"
29 #include "BC_OnedEAN13Reader.h"
30 #include "BC_OnedEAN13Writer.h"
CBC_OnedEAN13Writer()31 CBC_OnedEAN13Writer::CBC_OnedEAN13Writer() {
32 m_bLeftPadding = TRUE;
33 m_codeWidth = 3 + (7 * 6) + 5 + (7 * 6) + 3;
34 }
~CBC_OnedEAN13Writer()35 CBC_OnedEAN13Writer::~CBC_OnedEAN13Writer() {}
CheckContentValidity(const CFX_WideStringC & contents)36 FX_BOOL CBC_OnedEAN13Writer::CheckContentValidity(
37 const CFX_WideStringC& contents) {
38 for (int32_t i = 0; i < contents.GetLength(); i++) {
39 if (contents.GetAt(i) >= '0' && contents.GetAt(i) <= '9') {
40 continue;
41 } else {
42 return FALSE;
43 }
44 }
45 return TRUE;
46 }
FilterContents(const CFX_WideStringC & contents)47 CFX_WideString CBC_OnedEAN13Writer::FilterContents(
48 const CFX_WideStringC& contents) {
49 CFX_WideString filtercontents;
50 FX_WCHAR ch;
51 for (int32_t i = 0; i < contents.GetLength(); i++) {
52 ch = contents.GetAt(i);
53 if (ch > 175) {
54 i++;
55 continue;
56 }
57 if (ch >= '0' && ch <= '9') {
58 filtercontents += ch;
59 }
60 }
61 return filtercontents;
62 }
CalcChecksum(const CFX_ByteString & contents)63 int32_t CBC_OnedEAN13Writer::CalcChecksum(const CFX_ByteString& contents) {
64 int32_t odd = 0;
65 int32_t even = 0;
66 int32_t j = 1;
67 for (int32_t i = contents.GetLength() - 1; i >= 0; i--) {
68 if (j % 2) {
69 odd += FXSYS_atoi(contents.Mid(i, 1));
70 } else {
71 even += FXSYS_atoi(contents.Mid(i, 1));
72 }
73 j++;
74 }
75 int32_t checksum = (odd * 3 + even) % 10;
76 checksum = (10 - checksum) % 10;
77 return (checksum);
78 }
Encode(const CFX_ByteString & contents,BCFORMAT format,int32_t & outWidth,int32_t & outHeight,int32_t & e)79 uint8_t* CBC_OnedEAN13Writer::Encode(const CFX_ByteString& contents,
80 BCFORMAT format,
81 int32_t& outWidth,
82 int32_t& outHeight,
83 int32_t& e) {
84 uint8_t* ret = Encode(contents, format, outWidth, outHeight, 0, e);
85 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
86 return ret;
87 }
Encode(const CFX_ByteString & contents,BCFORMAT format,int32_t & outWidth,int32_t & outHeight,int32_t hints,int32_t & e)88 uint8_t* CBC_OnedEAN13Writer::Encode(const CFX_ByteString& contents,
89 BCFORMAT format,
90 int32_t& outWidth,
91 int32_t& outHeight,
92 int32_t hints,
93 int32_t& e) {
94 if (format != BCFORMAT_EAN_13) {
95 e = BCExceptionOnlyEncodeEAN_13;
96 }
97 uint8_t* ret =
98 CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e);
99 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
100 return ret;
101 }
Encode(const CFX_ByteString & contents,int32_t & outLength,int32_t & e)102 uint8_t* CBC_OnedEAN13Writer::Encode(const CFX_ByteString& contents,
103 int32_t& outLength,
104 int32_t& e) {
105 if (contents.GetLength() != 13) {
106 e = BCExceptionDigitLengthShould13;
107 return NULL;
108 }
109 m_iDataLenth = 13;
110 int32_t firstDigit = FXSYS_atoi(contents.Mid(0, 1));
111 int32_t parities = CBC_OnedEAN13Reader::FIRST_DIGIT_ENCODINGS[firstDigit];
112 outLength = m_codeWidth;
113 uint8_t* result = FX_Alloc(uint8_t, m_codeWidth);
114 int32_t pos = 0;
115 pos +=
116 AppendPattern(result, pos, CBC_OneDimReader::START_END_PATTERN, 3, 1, e);
117 if (e != BCExceptionNO) {
118 FX_Free(result);
119 return NULL;
120 }
121 int32_t i = 0;
122 for (i = 1; i <= 6; i++) {
123 int32_t digit = FXSYS_atoi(contents.Mid(i, 1));
124 if ((parities >> (6 - i) & 1) == 1) {
125 digit += 10;
126 }
127 pos += AppendPattern(result, pos, CBC_OneDimReader::L_AND_G_PATTERNS[digit],
128 4, 0, e);
129 if (e != BCExceptionNO) {
130 FX_Free(result);
131 return NULL;
132 }
133 }
134 pos += AppendPattern(result, pos, CBC_OneDimReader::MIDDLE_PATTERN, 5, 0, e);
135 if (e != BCExceptionNO) {
136 FX_Free(result);
137 return NULL;
138 }
139 for (i = 7; i <= 12; i++) {
140 int32_t digit = FXSYS_atoi(contents.Mid(i, 1));
141 pos += AppendPattern(result, pos, CBC_OneDimReader::L_PATTERNS[digit], 4, 1,
142 e);
143 if (e != BCExceptionNO) {
144 FX_Free(result);
145 return NULL;
146 }
147 }
148 pos +=
149 AppendPattern(result, pos, CBC_OneDimReader::START_END_PATTERN, 3, 1, e);
150 if (e != BCExceptionNO) {
151 FX_Free(result);
152 return NULL;
153 }
154 return result;
155 }
ShowChars(const CFX_WideStringC & contents,CFX_DIBitmap * pOutBitmap,CFX_RenderDevice * device,const CFX_Matrix * matrix,int32_t barWidth,int32_t multiple,int32_t & e)156 void CBC_OnedEAN13Writer::ShowChars(const CFX_WideStringC& contents,
157 CFX_DIBitmap* pOutBitmap,
158 CFX_RenderDevice* device,
159 const CFX_Matrix* matrix,
160 int32_t barWidth,
161 int32_t multiple,
162 int32_t& e) {
163 if (device == NULL && pOutBitmap == NULL) {
164 e = BCExceptionIllegalArgument;
165 return;
166 }
167 int32_t leftPadding = 7 * multiple;
168 int32_t leftPosition = 3 * multiple + leftPadding;
169 CFX_ByteString str = FX_UTF8Encode(contents);
170 int32_t iLen = str.GetLength();
171 FXTEXT_CHARPOS* pCharPos = FX_Alloc(FXTEXT_CHARPOS, iLen);
172 FXSYS_memset(pCharPos, 0, sizeof(FXTEXT_CHARPOS) * iLen);
173 CFX_FxgeDevice geBitmap;
174 if (pOutBitmap != NULL) {
175 geBitmap.Attach(pOutBitmap);
176 }
177 int32_t iFontSize = (int32_t)fabs(m_fFontSize);
178 int32_t iTextHeight = iFontSize + 1;
179 CFX_ByteString tempStr = str.Mid(1, 6);
180 int32_t strWidth = multiple * 42;
181 if (pOutBitmap == NULL) {
182 CFX_Matrix matr(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0);
183 CFX_FloatRect rect(
184 (FX_FLOAT)leftPosition, (FX_FLOAT)(m_Height - iTextHeight),
185 (FX_FLOAT)(leftPosition + strWidth - 0.5), (FX_FLOAT)m_Height);
186 matr.Concat(*matrix);
187 matr.TransformRect(rect);
188 FX_RECT re = rect.GetOutterRect();
189 device->FillRect(&re, m_backgroundColor);
190 CFX_FloatRect rect1(
191 (FX_FLOAT)(leftPosition + 47 * multiple),
192 (FX_FLOAT)(m_Height - iTextHeight),
193 (FX_FLOAT)(leftPosition + 47 * multiple + strWidth - 0.5),
194 (FX_FLOAT)m_Height);
195 CFX_Matrix matr1(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0);
196 matr1.Concat(*matrix);
197 matr1.TransformRect(rect1);
198 re = rect1.GetOutterRect();
199 device->FillRect(&re, m_backgroundColor);
200 int32_t strWidth1 = multiple * 7;
201 CFX_Matrix matr2(m_outputHScale, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
202 CFX_FloatRect rect2(0.0f, (FX_FLOAT)(m_Height - iTextHeight),
203 (FX_FLOAT)strWidth1 - 0.5f, (FX_FLOAT)m_Height);
204 matr2.Concat(*matrix);
205 matr2.TransformRect(rect2);
206 re = rect2.GetOutterRect();
207 device->FillRect(&re, m_backgroundColor);
208 }
209 FX_FLOAT blank = 0.0;
210 FX_FLOAT charsWidth = 0;
211 iLen = tempStr.GetLength();
212 if (pOutBitmap == NULL) {
213 strWidth = (int32_t)(strWidth * m_outputHScale);
214 }
215 CalcTextInfo(tempStr, pCharPos + 1, m_pFont, (FX_FLOAT)strWidth, iFontSize,
216 blank);
217 CFX_Matrix affine_matrix(1.0, 0.0, 0.0, -1.0, 0.0, (FX_FLOAT)iFontSize);
218 CFX_FxgeDevice ge;
219 if (pOutBitmap != NULL) {
220 ge.Create(strWidth, iTextHeight, FXDIB_Argb);
221 FX_RECT rect(0, 0, strWidth, iTextHeight);
222 ge.FillRect(&rect, m_backgroundColor);
223 ge.DrawNormalText(iLen, pCharPos + 1, m_pFont,
224 CFX_GEModule::Get()->GetFontCache(), (FX_FLOAT)iFontSize,
225 (CFX_Matrix*)&affine_matrix, m_fontColor,
226 FXTEXT_CLEARTYPE);
227 geBitmap.SetDIBits(ge.GetBitmap(), leftPosition, m_Height - iTextHeight);
228 } else {
229 CFX_Matrix affine_matrix1(1.0, 0.0, 0.0, -1.0,
230 (FX_FLOAT)leftPosition * m_outputHScale,
231 (FX_FLOAT)(m_Height - iTextHeight) + iFontSize);
232 if (matrix != NULL) {
233 affine_matrix1.Concat(*matrix);
234 }
235 device->DrawNormalText(iLen, pCharPos + 1, m_pFont,
236 CFX_GEModule::Get()->GetFontCache(),
237 (FX_FLOAT)iFontSize, (CFX_Matrix*)&affine_matrix1,
238 m_fontColor, FXTEXT_CLEARTYPE);
239 }
240 tempStr = str.Mid(7, 6);
241 iLen = tempStr.GetLength();
242 charsWidth = 0.0f;
243 CalcTextInfo(tempStr, pCharPos + 7, m_pFont, (FX_FLOAT)strWidth, iFontSize,
244 blank);
245 if (pOutBitmap != NULL) {
246 FX_RECT rect1(0, 0, strWidth, iTextHeight);
247 ge.FillRect(&rect1, m_backgroundColor);
248 ge.DrawNormalText(iLen, pCharPos + 7, m_pFont,
249 CFX_GEModule::Get()->GetFontCache(), (FX_FLOAT)iFontSize,
250 (CFX_Matrix*)&affine_matrix, m_fontColor,
251 FXTEXT_CLEARTYPE);
252 geBitmap.SetDIBits(ge.GetBitmap(), leftPosition + 47 * multiple,
253 m_Height - iTextHeight);
254 } else {
255 CFX_Matrix affine_matrix1(
256 1.0, 0.0, 0.0, -1.0,
257 (FX_FLOAT)(leftPosition + 47 * multiple) * m_outputHScale,
258 (FX_FLOAT)(m_Height - iTextHeight + iFontSize));
259 if (matrix != NULL) {
260 affine_matrix1.Concat(*matrix);
261 }
262 device->DrawNormalText(iLen, pCharPos + 7, m_pFont,
263 CFX_GEModule::Get()->GetFontCache(),
264 (FX_FLOAT)iFontSize, (CFX_Matrix*)&affine_matrix1,
265 m_fontColor, FXTEXT_CLEARTYPE);
266 }
267 tempStr = str.Mid(0, 1);
268 iLen = tempStr.GetLength();
269 strWidth = multiple * 7;
270 if (pOutBitmap == NULL) {
271 strWidth = (int32_t)(strWidth * m_outputHScale);
272 }
273 CalcTextInfo(tempStr, pCharPos, m_pFont, (FX_FLOAT)strWidth, iFontSize,
274 blank);
275 if (pOutBitmap != NULL) {
276 delete ge.GetBitmap();
277 ge.Create(strWidth, iTextHeight, FXDIB_Argb);
278 ge.GetBitmap()->Clear(m_backgroundColor);
279 ge.DrawNormalText(iLen, pCharPos, m_pFont,
280 CFX_GEModule::Get()->GetFontCache(), (FX_FLOAT)iFontSize,
281 (CFX_Matrix*)&affine_matrix, m_fontColor,
282 FXTEXT_CLEARTYPE);
283 geBitmap.SetDIBits(ge.GetBitmap(), 0, m_Height - iTextHeight);
284 } else {
285 CFX_Matrix affine_matrix1(1.0, 0.0, 0.0, -1.0, 0.0,
286 (FX_FLOAT)(m_Height - iTextHeight + iFontSize));
287 if (matrix != NULL) {
288 affine_matrix1.Concat(*matrix);
289 }
290 device->DrawNormalText(iLen, pCharPos, m_pFont,
291 CFX_GEModule::Get()->GetFontCache(),
292 (FX_FLOAT)iFontSize, (CFX_Matrix*)&affine_matrix1,
293 m_fontColor, FXTEXT_CLEARTYPE);
294 }
295 FX_Free(pCharPos);
296 }
RenderResult(const CFX_WideStringC & contents,uint8_t * code,int32_t codeLength,FX_BOOL isDevice,int32_t & e)297 void CBC_OnedEAN13Writer::RenderResult(const CFX_WideStringC& contents,
298 uint8_t* code,
299 int32_t codeLength,
300 FX_BOOL isDevice,
301 int32_t& e) {
302 CBC_OneDimWriter::RenderResult(contents, code, codeLength, isDevice, e);
303 }
304