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