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