Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / xfa / src / fxbarcode / src / BC_OnedCode128Writer.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_OnedCode128Reader.h"\r
13 #include "include/BC_OnedCode128Writer.h"\r
14 const FX_INT32 CBC_OnedCode128Writer::CODE_CODE_B = 100;\r
15 const FX_INT32 CBC_OnedCode128Writer::CODE_CODE_C = 99;\r
16 const FX_INT32 CBC_OnedCode128Writer::CODE_START_B = 104;\r
17 const FX_INT32 CBC_OnedCode128Writer::CODE_START_C = 105;\r
18 const FX_INT32 CBC_OnedCode128Writer::CODE_STOP = 106;\r
19 CBC_OnedCode128Writer::CBC_OnedCode128Writer()\r
20 {\r
21     m_codeFormat = BC_CODE128_B;\r
22 }\r
23 CBC_OnedCode128Writer::CBC_OnedCode128Writer(BC_TYPE type)\r
24 {\r
25     m_codeFormat = type;\r
26 }\r
27 CBC_OnedCode128Writer::~CBC_OnedCode128Writer()\r
28 {\r
29 }\r
30 BC_TYPE CBC_OnedCode128Writer::GetType()\r
31 {\r
32     return m_codeFormat;\r
33 }\r
34 FX_BOOL CBC_OnedCode128Writer::CheckContentValidity(FX_WSTR contents)\r
35 {\r
36     FX_BOOL ret = TRUE;\r
37     FX_INT32 position = 0;\r
38     FX_INT32 patternIndex = -1;\r
39     if (m_codeFormat == BC_CODE128_B || m_codeFormat == BC_CODE128_C) {\r
40         while (position < contents.GetLength()) {\r
41             patternIndex = (FX_INT32)contents.GetAt(position);\r
42             if (patternIndex >= 32 && patternIndex <= 126 && patternIndex != 34) {\r
43                 position++;\r
44                 continue;\r
45             } else {\r
46                 ret = FALSE;\r
47                 break;\r
48             }\r
49             position ++;\r
50         }\r
51     } else {\r
52         ret = FALSE;\r
53     }\r
54     return ret;\r
55 }\r
56 CFX_WideString CBC_OnedCode128Writer::FilterContents(FX_WSTR contents)\r
57 {\r
58     CFX_WideString filterChineseChar;\r
59     FX_WCHAR ch;\r
60     for (FX_INT32 i = 0; i < contents.GetLength(); i++) {\r
61         ch = contents.GetAt(i);\r
62         if(ch > 175) {\r
63             i++;\r
64             continue;\r
65         }\r
66         filterChineseChar += ch;\r
67     }\r
68     CFX_WideString filtercontents;\r
69     if (m_codeFormat == BC_CODE128_B) {\r
70         for (FX_INT32 i = 0; i < filterChineseChar.GetLength(); i++) {\r
71             ch = filterChineseChar.GetAt(i);\r
72             if (ch >= 32 && ch <= 126) {\r
73                 filtercontents += ch;\r
74             } else {\r
75                 continue;\r
76             }\r
77         }\r
78     } else if (m_codeFormat == BC_CODE128_C) {\r
79         for (FX_INT32 i = 0; i < filterChineseChar.GetLength(); i++) {\r
80             ch = filterChineseChar.GetAt(i);\r
81             if (ch >= 32 && ch <= 106) {\r
82                 filtercontents += ch;\r
83             } else {\r
84                 continue;\r
85             }\r
86         }\r
87     } else {\r
88         filtercontents = contents;\r
89     }\r
90     return filtercontents;\r
91 }\r
92 FX_BOOL CBC_OnedCode128Writer::SetTextLocation(BC_TEXT_LOC location)\r
93 {\r
94     if ( location < BC_TEXT_LOC_NONE || location > BC_TEXT_LOC_BELOWEMBED) {\r
95         return FALSE;\r
96     }\r
97     m_locTextLoc = location;\r
98     return TRUE;\r
99 }\r
100 FX_BYTE *CBC_OnedCode128Writer::Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e)\r
101 {\r
102     if(format != BCFORMAT_CODE_128) {\r
103         e = BCExceptionOnlyEncodeCODE_128;\r
104         return NULL;\r
105     }\r
106     FX_BYTE *ret = CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e);\r
107     BC_EXCEPTION_CHECK_ReturnValue(e, NULL);\r
108     return ret;\r
109 }\r
110 FX_BYTE *CBC_OnedCode128Writer::Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e)\r
111 {\r
112     FX_BYTE *ret =  Encode(contents, format, outWidth, outHeight, 0, e);\r
113     BC_EXCEPTION_CHECK_ReturnValue(e, NULL);\r
114     return ret;\r
115 }\r
116 FX_BOOL CBC_OnedCode128Writer::IsDigits(const CFX_ByteString &contents, FX_INT32 start, FX_INT32 length)\r
117 {\r
118     FX_INT32 end = start + length;\r
119     for (FX_INT32 i = start; i < end; i++) {\r
120         if (contents[i] < '0' || contents[i] > '9') {\r
121             return FALSE;\r
122         }\r
123     }\r
124     return TRUE;\r
125 }\r
126 FX_BYTE *CBC_OnedCode128Writer::Encode(const CFX_ByteString &contents, FX_INT32 &outLength, FX_INT32 &e)\r
127 {\r
128     FX_INT32 length = contents.GetLength();\r
129     if(contents.GetLength() < 1 || contents.GetLength() > 80) {\r
130         e = BCExceptionContentsLengthShouldBetween1and80;\r
131         return NULL;\r
132     }\r
133     CFX_PtrArray patterns;\r
134     FX_INT32 checkSum = 0;\r
135     if (m_codeFormat == BC_CODE128_B) {\r
136         checkSum = Encode128B(contents, patterns);\r
137     } else if (m_codeFormat == BC_CODE128_C)    {\r
138         checkSum = Encode128C(contents, patterns);\r
139     } else {\r
140         e = BCExceptionFormatException;\r
141         return NULL;\r
142     }\r
143     checkSum %= 103;\r
144     patterns.Add((FX_INT32*)CBC_OnedCode128Reader::CODE_PATTERNS[checkSum]);\r
145     patterns.Add((FX_INT32*)CBC_OnedCode128Reader::CODE_PATTERNS[CODE_STOP]);\r
146     m_iContentLen = contents.GetLength() + 3;\r
147     FX_INT32 codeWidth = 0;\r
148     for(FX_INT32 k = 0; k < patterns.GetSize(); k++) {\r
149         FX_INT32 *pattern = (FX_INT32*)patterns[k];\r
150         for(FX_INT32 j = 0; j < 7; j++) {\r
151             codeWidth += pattern[j];\r
152         }\r
153     }\r
154     outLength = codeWidth;\r
155     FX_BYTE *result = FX_Alloc(FX_BYTE, outLength);\r
156     FX_INT32 pos = 0;\r
157     for(FX_INT32 j = 0; j < patterns.GetSize(); j++) {\r
158         FX_INT32* pattern = (FX_INT32*)patterns[j];\r
159         pos += AppendPattern(result, pos, pattern, 7, 1, e);\r
160         if (e != BCExceptionNO) {\r
161             FX_Free (result);\r
162             return NULL;\r
163         }\r
164     }\r
165     return result;\r
166 }\r
167 FX_INT32 CBC_OnedCode128Writer::Encode128B(const CFX_ByteString &contents,  CFX_PtrArray &patterns)\r
168 {\r
169     FX_INT32 checkSum = 0;\r
170     FX_INT32 checkWeight = 1;\r
171     FX_INT32 position = 0;\r
172     patterns.Add((FX_INT32*)CBC_OnedCode128Reader::CODE_PATTERNS[CODE_START_B]);\r
173     checkSum += CODE_START_B * checkWeight;\r
174     while (position < contents.GetLength()) {\r
175         FX_INT32 patternIndex = 0;\r
176         patternIndex = contents[position] - ' ';\r
177         position += 1;\r
178         patterns.Add((FX_INT32*)CBC_OnedCode128Reader::CODE_PATTERNS[patternIndex]);\r
179         checkSum += patternIndex * checkWeight;\r
180         if (position != 0) {\r
181             checkWeight++;\r
182         }\r
183     }\r
184     return checkSum;\r
185 }\r
186 FX_INT32 CBC_OnedCode128Writer::Encode128C(const CFX_ByteString &contents,  CFX_PtrArray &patterns)\r
187 {\r
188     FX_INT32 checkSum = 0;\r
189     FX_INT32 checkWeight = 1;\r
190     FX_INT32 position = 0;\r
191     patterns.Add((FX_INT32*)CBC_OnedCode128Reader::CODE_PATTERNS[CODE_START_C]);\r
192     checkSum += CODE_START_C * checkWeight;\r
193     while (position < contents.GetLength()) {\r
194         FX_INT32 patternIndex = 0;\r
195         FX_CHAR ch = contents.GetAt(position);\r
196         if (ch < '0' || ch > '9') {\r
197             patternIndex = (FX_INT32)ch;\r
198             position++;\r
199         } else {\r
200             patternIndex = FXSYS_atoi(contents.Mid(position, 2));\r
201             if (contents.GetAt(position + 1) < '0' || contents.GetAt(position + 1) > '9') {\r
202                 position += 1;\r
203             } else {\r
204                 position += 2;\r
205             }\r
206         }\r
207         patterns.Add((FX_INT32*)CBC_OnedCode128Reader::CODE_PATTERNS[patternIndex]);\r
208         checkSum += patternIndex * checkWeight;\r
209         if (position != 0) {\r
210             checkWeight++;\r
211         }\r
212     }\r
213     return checkSum;\r
214 }\r