Merge to XFA: Kill FXSYS_mem{cpy,cmp,set.move}{32,8}.
[pdfium.git] / xfa / src / fxbarcode / oned / BC_OnedEAN13Writer.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 2009 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_OneDimReader.h"\r
28 #include "BC_OneDimWriter.h"\r
29 #include "BC_OnedEAN13Reader.h"\r
30 #include "BC_OnedEAN13Writer.h"\r
31 CBC_OnedEAN13Writer::CBC_OnedEAN13Writer()\r
32 {\r
33     m_bLeftPadding = TRUE;\r
34     m_codeWidth = 3 +\r
35                   (7 * 6) +\r
36                   5 +\r
37                   (7 * 6) +\r
38                   3;\r
39 }\r
40 CBC_OnedEAN13Writer::~CBC_OnedEAN13Writer()\r
41 {\r
42 }\r
43 FX_BOOL CBC_OnedEAN13Writer::CheckContentValidity(const CFX_WideStringC& contents)\r
44 {\r
45     for (int32_t i = 0; i < contents.GetLength(); i++) {\r
46         if (contents.GetAt(i) >= '0' && contents.GetAt(i) <= '9') {\r
47             continue;\r
48         } else {\r
49             return FALSE;\r
50         }\r
51     }\r
52     return TRUE;\r
53 }\r
54 CFX_WideString  CBC_OnedEAN13Writer::FilterContents(const CFX_WideStringC& contents)\r
55 {\r
56     CFX_WideString filtercontents;\r
57     FX_WCHAR ch;\r
58     for (int32_t i = 0; i < contents.GetLength(); i++) {\r
59         ch = contents.GetAt(i);\r
60         if(ch > 175) {\r
61             i++;\r
62             continue;\r
63         }\r
64         if (ch >= '0' && ch <= '9') {\r
65             filtercontents += ch;\r
66         }\r
67     }\r
68     return filtercontents;\r
69 }\r
70 int32_t CBC_OnedEAN13Writer::CalcChecksum(const CFX_ByteString &contents)\r
71 {\r
72     int32_t odd = 0;\r
73     int32_t even = 0;\r
74     int32_t j = 1;\r
75     for(int32_t i = contents.GetLength() - 1; i >= 0; i--) {\r
76         if(j % 2) {\r
77             odd += FXSYS_atoi(contents.Mid(i, 1));\r
78         } else {\r
79             even += FXSYS_atoi(contents.Mid(i, 1));\r
80         }\r
81         j++;\r
82     }\r
83     int32_t checksum = (odd * 3 + even) % 10;\r
84     checksum = (10 - checksum) % 10;\r
85     return (checksum);\r
86 }\r
87 uint8_t *CBC_OnedEAN13Writer::Encode(const CFX_ByteString &contents, BCFORMAT format, int32_t &outWidth, int32_t &outHeight, int32_t &e)\r
88 {\r
89     uint8_t *ret = Encode(contents, format, outWidth, outHeight, 0, e);\r
90     BC_EXCEPTION_CHECK_ReturnValue(e, NULL);\r
91     return ret;\r
92 }\r
93 uint8_t *CBC_OnedEAN13Writer::Encode(const CFX_ByteString &contents, BCFORMAT format, int32_t &outWidth, int32_t &outHeight, int32_t hints, int32_t &e)\r
94 {\r
95     if(format != BCFORMAT_EAN_13) {\r
96         e = BCExceptionOnlyEncodeEAN_13;\r
97     }\r
98     uint8_t *ret = CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e);\r
99     BC_EXCEPTION_CHECK_ReturnValue(e, NULL);\r
100     return ret;\r
101 }\r
102 uint8_t *CBC_OnedEAN13Writer::Encode(const CFX_ByteString &contents, int32_t &outLength, int32_t &e)\r
103 {\r
104     if (contents.GetLength() != 13) {\r
105         e = BCExceptionDigitLengthShould13;\r
106         return NULL;\r
107     }\r
108     m_iDataLenth = 13;\r
109     int32_t firstDigit = FXSYS_atoi(contents.Mid(0, 1));\r
110     int32_t parities = CBC_OnedEAN13Reader::FIRST_DIGIT_ENCODINGS[firstDigit];\r
111     outLength = m_codeWidth;\r
112     uint8_t *result = FX_Alloc(uint8_t, m_codeWidth);\r
113     int32_t pos = 0;\r
114     pos += AppendPattern(result, pos, CBC_OneDimReader::START_END_PATTERN, 3, 1, e);\r
115     if (e != BCExceptionNO) {\r
116         FX_Free (result);\r
117         return NULL;\r
118     }\r
119     int32_t i = 0;\r
120     for ( i = 1; i <= 6; i++) {\r
121         int32_t digit = FXSYS_atoi(contents.Mid(i, 1));\r
122         if ((parities >> (6 - i) & 1) == 1) {\r
123             digit += 10;\r
124         }\r
125         pos += AppendPattern(result, pos, CBC_OneDimReader::L_AND_G_PATTERNS[digit], 4, 0, e);\r
126         if (e != BCExceptionNO) {\r
127             FX_Free (result);\r
128             return NULL;\r
129         }\r
130     }\r
131     pos += AppendPattern(result, pos, CBC_OneDimReader::MIDDLE_PATTERN, 5, 0, e);\r
132     if (e != BCExceptionNO) {\r
133         FX_Free (result);\r
134         return NULL;\r
135     }\r
136     for (i = 7; i <= 12; i++) {\r
137         int32_t digit = FXSYS_atoi(contents.Mid(i, 1));\r
138         pos += AppendPattern(result, pos, CBC_OneDimReader::L_PATTERNS[digit], 4, 1, e);\r
139         if (e != BCExceptionNO) {\r
140             FX_Free (result);\r
141             return NULL;\r
142         }\r
143     }\r
144     pos += AppendPattern(result, pos, CBC_OneDimReader::START_END_PATTERN, 3, 1, e);\r
145     if (e != BCExceptionNO) {\r
146         FX_Free (result);\r
147         return NULL;\r
148     }\r
149     return result;\r
150 }\r
151 void CBC_OnedEAN13Writer::ShowChars(const CFX_WideStringC& contents, CFX_DIBitmap *pOutBitmap, CFX_RenderDevice* device, const CFX_Matrix* matrix, int32_t barWidth, int32_t multiple, int32_t &e)\r
152 {\r
153     if (device == NULL && pOutBitmap == NULL) {\r
154         e = BCExceptionIllegalArgument;\r
155         return;\r
156     }\r
157     int32_t leftPadding = 7 * multiple;\r
158     int32_t leftPosition = 3 * multiple + leftPadding;\r
159     CFX_ByteString str = FX_UTF8Encode(contents);\r
160     int32_t iLen = str.GetLength();\r
161     FXTEXT_CHARPOS* pCharPos = FX_Alloc(FXTEXT_CHARPOS, iLen);\r
162     if (!pCharPos) {\r
163         return;\r
164     }\r
165     FXSYS_memset(pCharPos, 0, sizeof(FXTEXT_CHARPOS) * iLen);\r
166     CFX_FxgeDevice geBitmap;\r
167     if (pOutBitmap != NULL) {\r
168         geBitmap.Attach(pOutBitmap);\r
169     }\r
170     int32_t iFontSize = (int32_t)fabs(m_fFontSize);\r
171     int32_t iTextHeight = iFontSize + 1;\r
172     CFX_ByteString tempStr = str.Mid(1, 6);\r
173     int32_t strWidth = multiple * 42;\r
174     if (pOutBitmap == NULL) {\r
175         CFX_Matrix matr(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0);\r
176         CFX_FloatRect rect((FX_FLOAT)leftPosition, (FX_FLOAT)(m_Height - iTextHeight), (FX_FLOAT)(leftPosition + strWidth - 0.5), (FX_FLOAT)m_Height);\r
177         matr.Concat(*matrix);\r
178         matr.TransformRect(rect);\r
179         FX_RECT re = rect.GetOutterRect();\r
180         device->FillRect(&re, m_backgroundColor);\r
181         CFX_FloatRect rect1((FX_FLOAT)(leftPosition + 47 * multiple), (FX_FLOAT)(m_Height - iTextHeight), (FX_FLOAT)(leftPosition + 47 * multiple + strWidth - 0.5), (FX_FLOAT)m_Height);\r
182         CFX_Matrix matr1(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0);\r
183         matr1.Concat(*matrix);\r
184         matr1.TransformRect(rect1);\r
185         re = rect1.GetOutterRect();\r
186         device->FillRect(&re, m_backgroundColor);\r
187         int32_t strWidth1 = multiple * 7;\r
188         CFX_Matrix matr2(m_outputHScale, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);\r
189         CFX_FloatRect rect2(0.0f, (FX_FLOAT)(m_Height - iTextHeight), (FX_FLOAT)strWidth1 - 0.5f, (FX_FLOAT)m_Height);\r
190         matr2.Concat(*matrix);\r
191         matr2.TransformRect(rect2);\r
192         re = rect2.GetOutterRect();\r
193         device->FillRect(&re, m_backgroundColor);\r
194     }\r
195     FX_FLOAT blank = 0.0;\r
196     FX_FLOAT charsWidth = 0;\r
197     iLen = tempStr.GetLength();\r
198     if (pOutBitmap == NULL) {\r
199         strWidth = (int32_t)(strWidth * m_outputHScale);\r
200     }\r
201     CalcTextInfo(tempStr, pCharPos + 1, m_pFont, (FX_FLOAT)strWidth, iFontSize, blank);\r
202     CFX_AffineMatrix affine_matrix(1.0, 0.0, 0.0, -1.0, 0.0, (FX_FLOAT)iFontSize);\r
203     CFX_FxgeDevice ge;\r
204     if (pOutBitmap != NULL) {\r
205         ge.Create(strWidth, iTextHeight, FXDIB_Argb);\r
206         FX_RECT rect(0, 0, strWidth, iTextHeight);\r
207         ge.FillRect(&rect, m_backgroundColor);\r
208         ge.DrawNormalText(iLen,\r
209                           pCharPos + 1,\r
210                           m_pFont,\r
211                           CFX_GEModule::Get()->GetFontCache(),\r
212                           (FX_FLOAT)iFontSize ,\r
213                           (CFX_AffineMatrix *) &affine_matrix,\r
214                           m_fontColor, FXTEXT_CLEARTYPE);\r
215         geBitmap.SetDIBits(ge.GetBitmap(), leftPosition, m_Height - iTextHeight);\r
216     } else {\r
217         CFX_AffineMatrix affine_matrix1(1.0, 0.0, 0.0, -1.0, (FX_FLOAT)leftPosition * m_outputHScale, (FX_FLOAT)(m_Height - iTextHeight) + iFontSize);\r
218         if (matrix != NULL) {\r
219             affine_matrix1.Concat(*matrix);\r
220         }\r
221         device->DrawNormalText(iLen,\r
222                                pCharPos + 1,\r
223                                m_pFont,\r
224                                CFX_GEModule::Get()->GetFontCache(),\r
225                                (FX_FLOAT)iFontSize ,\r
226                                (CFX_AffineMatrix *) &affine_matrix1,\r
227                                m_fontColor, FXTEXT_CLEARTYPE);\r
228     }\r
229     tempStr = str.Mid(7, 6);\r
230     iLen = tempStr.GetLength();\r
231     charsWidth = 0.0f;\r
232     CalcTextInfo(tempStr, pCharPos + 7, m_pFont, (FX_FLOAT)strWidth, iFontSize, blank);\r
233     if(pOutBitmap != NULL) {\r
234         FX_RECT rect1(0, 0, strWidth, iTextHeight);\r
235         ge.FillRect(&rect1, m_backgroundColor);\r
236         ge.DrawNormalText(iLen,\r
237                           pCharPos + 7,\r
238                           m_pFont,\r
239                           CFX_GEModule::Get()->GetFontCache(),\r
240                           (FX_FLOAT)iFontSize ,\r
241                           (CFX_AffineMatrix *) &affine_matrix,\r
242                           m_fontColor, FXTEXT_CLEARTYPE);\r
243         geBitmap.SetDIBits(ge.GetBitmap(), leftPosition + 47 * multiple, m_Height - iTextHeight);\r
244     } else {\r
245         CFX_AffineMatrix affine_matrix1(1.0, 0.0, 0.0, -1.0, (FX_FLOAT)(leftPosition + 47 * multiple) * m_outputHScale, (FX_FLOAT)(m_Height - iTextHeight + iFontSize));\r
246         if (matrix != NULL) {\r
247             affine_matrix1.Concat(*matrix);\r
248         }\r
249         device->DrawNormalText(iLen,\r
250                                pCharPos + 7,\r
251                                m_pFont,\r
252                                CFX_GEModule::Get()->GetFontCache(),\r
253                                (FX_FLOAT)iFontSize ,\r
254                                (CFX_AffineMatrix *) &affine_matrix1,\r
255                                m_fontColor, FXTEXT_CLEARTYPE);\r
256     }\r
257     tempStr = str.Mid(0, 1);\r
258     iLen = tempStr.GetLength();\r
259     strWidth = multiple * 7;\r
260     if (pOutBitmap == NULL) {\r
261         strWidth = (int32_t)(strWidth * m_outputHScale);\r
262     }\r
263     CalcTextInfo(tempStr, pCharPos, m_pFont, (FX_FLOAT)strWidth, iFontSize, blank);\r
264     if(pOutBitmap != NULL) {\r
265         delete ge.GetBitmap();\r
266         ge.Create(strWidth, iTextHeight, FXDIB_Argb);\r
267         ge.GetBitmap()->Clear(m_backgroundColor);\r
268         ge.DrawNormalText(iLen,\r
269                           pCharPos,\r
270                           m_pFont,\r
271                           CFX_GEModule::Get()->GetFontCache(),\r
272                           (FX_FLOAT)iFontSize ,\r
273                           (CFX_AffineMatrix *) &affine_matrix,\r
274                           m_fontColor, FXTEXT_CLEARTYPE);\r
275         geBitmap.SetDIBits(ge.GetBitmap(), 0, m_Height - iTextHeight);\r
276     } else {\r
277         CFX_AffineMatrix affine_matrix1(1.0, 0.0, 0.0, -1.0, 0.0, (FX_FLOAT)(m_Height - iTextHeight + iFontSize));\r
278         if (matrix != NULL) {\r
279             affine_matrix1.Concat(*matrix);\r
280         }\r
281         device->DrawNormalText(iLen,\r
282                                pCharPos,\r
283                                m_pFont,\r
284                                CFX_GEModule::Get()->GetFontCache(),\r
285                                (FX_FLOAT)iFontSize ,\r
286                                (CFX_AffineMatrix *) &affine_matrix1,\r
287                                m_fontColor, FXTEXT_CLEARTYPE);\r
288     }\r
289     FX_Free(pCharPos);\r
290 }\r
291 void CBC_OnedEAN13Writer::RenderResult(const CFX_WideStringC& contents, uint8_t* code, int32_t codeLength, FX_BOOL isDevice, int32_t &e)\r
292 {\r
293     CBC_OneDimWriter::RenderResult(contents, code, codeLength, isDevice, e);\r
294 }\r