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