Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / xfa / src / fxbarcode / src / BC_OnedCodaBarWriter.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_CommonBitArray.h"\r
12 #include "include/BC_OneDimWriter.h"\r
13 #include "include/BC_OnedCodaBarReader.h"\r
14 #include "include/BC_OnedCodaBarWriter.h"\r
15 #include "include/BC_CommonBitMatrix.h"\r
16 const FX_CHAR CBC_OnedCodaBarWriter::START_END_CHARS[] = {'A', 'B', 'C', 'D', 'T', 'N', '*', 'E', 'a', 'b', 'c', 'd', 't', 'n', 'e'};\r
17 const FX_CHAR CBC_OnedCodaBarWriter::CONTENT_CHARS[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '$', '/', ':', '+', '.'};\r
18 CBC_OnedCodaBarWriter::CBC_OnedCodaBarWriter()\r
19 {\r
20     m_chStart                   = 'A';\r
21     m_chEnd                             = 'B';\r
22     m_iWideNarrRatio    = 2;\r
23 }\r
24 CBC_OnedCodaBarWriter::~CBC_OnedCodaBarWriter()\r
25 {\r
26 }\r
27 FX_BOOL CBC_OnedCodaBarWriter::SetStartChar(FX_CHAR start)\r
28 {\r
29     for (FX_INT32 i = 0; i < sizeof(START_END_CHARS) / sizeof(FX_CHAR); i++) {\r
30         if (START_END_CHARS[i] == start) {\r
31             m_chStart = start;\r
32             return TRUE;\r
33         }\r
34     }\r
35     return FALSE;\r
36 }\r
37 FX_BOOL CBC_OnedCodaBarWriter::SetEndChar(FX_CHAR end)\r
38 {\r
39     for (FX_INT32 i = 0; i < sizeof(START_END_CHARS) / sizeof(FX_CHAR); i++) {\r
40         if (START_END_CHARS[i] == end) {\r
41             m_chEnd = end;\r
42             return TRUE;\r
43         }\r
44     }\r
45     return FALSE;\r
46 }\r
47 void CBC_OnedCodaBarWriter::SetDataLength(FX_INT32 length)\r
48 {\r
49     m_iDataLenth = length + 2;\r
50 }\r
51 FX_BOOL CBC_OnedCodaBarWriter::SetTextLocation(BC_TEXT_LOC location)\r
52 {\r
53     if ( location < BC_TEXT_LOC_NONE || location > BC_TEXT_LOC_BELOWEMBED) {\r
54         return FALSE;\r
55     }\r
56     m_locTextLoc = location;\r
57     return TRUE;\r
58 }\r
59 FX_BOOL CBC_OnedCodaBarWriter::SetWideNarrowRatio(FX_INT32 ratio)\r
60 {\r
61     if(ratio < 2 || ratio > 3) {\r
62         return FALSE;\r
63     }\r
64     m_iWideNarrRatio = ratio;\r
65     return TRUE;\r
66 }\r
67 FX_BOOL CBC_OnedCodaBarWriter::FindChar(FX_WCHAR ch, FX_BOOL isContent)\r
68 {\r
69     if(isContent) {\r
70         for(FX_INT32 i = 0 ; i < sizeof(CONTENT_CHARS) / sizeof(FX_CHAR) ; i++) {\r
71             if(ch == (FX_WCHAR)CONTENT_CHARS[i]) {\r
72                 return TRUE;\r
73             }\r
74         }\r
75         for(FX_INT32 j = 0 ; j < sizeof(START_END_CHARS) / sizeof(FX_CHAR) ; j++) {\r
76             if(ch == (FX_WCHAR)START_END_CHARS[j]) {\r
77                 return TRUE;\r
78             }\r
79         }\r
80         return FALSE;\r
81     } else {\r
82         for(FX_INT32 i = 0 ; i < sizeof(CONTENT_CHARS) / sizeof(FX_CHAR) ; i++) {\r
83             if(ch == (FX_WCHAR)CONTENT_CHARS[i]) {\r
84                 return TRUE;\r
85             }\r
86         }\r
87         return FALSE;\r
88     }\r
89 }\r
90 FX_BOOL CBC_OnedCodaBarWriter::CheckContentValidity(FX_WSTR contents)\r
91 {\r
92     FX_WCHAR ch;\r
93     FX_INT32 index = 0;\r
94     for (index = 0; index < contents.GetLength(); index++) {\r
95         ch = contents.GetAt(index);\r
96         if (FindChar(ch, FALSE)) {\r
97             continue;\r
98         } else {\r
99             return FALSE;\r
100         }\r
101     }\r
102     return TRUE;\r
103 }\r
104 CFX_WideString CBC_OnedCodaBarWriter::FilterContents(FX_WSTR contents)\r
105 {\r
106     CFX_WideString filtercontents;\r
107     FX_WCHAR ch;\r
108     for (FX_INT32 index = 0; index < contents.GetLength(); index ++) {\r
109         ch = contents.GetAt(index);\r
110         if(ch > 175) {\r
111             index++;\r
112             continue;\r
113         }\r
114         if (FindChar(ch, TRUE)) {\r
115             filtercontents += ch;\r
116         } else {\r
117             continue;\r
118         }\r
119     }\r
120     return filtercontents;\r
121 }\r
122 FX_BYTE *CBC_OnedCodaBarWriter::Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e)\r
123 {\r
124     FX_BYTE *ret = Encode(contents, format, outWidth, outHeight, 0 , e);\r
125     BC_EXCEPTION_CHECK_ReturnValue(e, NULL);\r
126     return ret;\r
127 }\r
128 FX_BYTE *CBC_OnedCodaBarWriter::Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e)\r
129 {\r
130     if(format != BCFORMAT_CODABAR) {\r
131         e = BCExceptionOnlyEncodeCODEBAR;\r
132         return NULL;\r
133     }\r
134     FX_BYTE *ret = CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e);\r
135     BC_EXCEPTION_CHECK_ReturnValue(e, NULL);\r
136     return ret;\r
137 }\r
138 FX_BYTE* CBC_OnedCodaBarWriter::Encode(const CFX_ByteString &contents, FX_INT32 &outLength, FX_INT32 &e)\r
139 {\r
140     CBC_OnedCodaBarReader CodaBarR;\r
141     CFX_ByteString data = m_chStart + contents + m_chEnd;\r
142     m_iContentLen = data.GetLength();\r
143     FX_BYTE *result = FX_Alloc(FX_BYTE, m_iWideNarrRatio * 7 * data.GetLength());\r
144     FX_CHAR ch;\r
145     FX_INT32 position = 0;\r
146     for (FX_INT32 index = 0; index < data.GetLength(); index++) {\r
147         ch = data.GetAt(index);\r
148         if (((ch >= 'a') && (ch <= 'z'))) {\r
149             ch = ch - 32;\r
150         }\r
151         switch (ch) {\r
152             case 'T':\r
153                 ch = 'A';\r
154                 break;\r
155             case 'N':\r
156                 ch = 'B';\r
157                 break;\r
158             case '*':\r
159                 ch = 'C';\r
160                 break;\r
161             case 'E':\r
162                 ch = 'D';\r
163                 break;\r
164             default:\r
165                 break;\r
166         }\r
167         FX_INT32 code = 0;\r
168         FX_INT32 len =  (FX_INT32)strlen(CodaBarR.ALPHABET_STRING);\r
169         for (FX_INT32 i = 0; i < len; i++) {\r
170             if (ch == CodaBarR.ALPHABET_STRING[i]) {\r
171                 code = CodaBarR.CHARACTER_ENCODINGS[i];\r
172                 break;\r
173             }\r
174         }\r
175         FX_BYTE color = 1;\r
176         FX_INT32 counter = 0;\r
177         FX_INT32 bit = 0;\r
178         while (bit < 7) {\r
179             result[position] = color;\r
180             position++;\r
181             if (((code >> (6 - bit)) & 1) == 0 || counter == m_iWideNarrRatio - 1) {\r
182                 color = !color;\r
183                 bit++;\r
184                 counter = 0;\r
185             } else {\r
186                 counter++;\r
187             }\r
188         }\r
189         if (index < data.GetLength() - 1) {\r
190             result[position] = 0;\r
191             position ++;\r
192         }\r
193     }\r
194     outLength = position;\r
195     return result;\r
196 }\r
197 CFX_WideString CBC_OnedCodaBarWriter::encodedContents(FX_WSTR contents)\r
198 {\r
199     CFX_WideString strStart(m_chStart);\r
200     CFX_WideString strEnd(m_chEnd);\r
201     return strStart + contents + strEnd;\r
202 }\r
203 void CBC_OnedCodaBarWriter::RenderResult(FX_WSTR contents, FX_BYTE* code, FX_INT32 codeLength, FX_BOOL isDevice, FX_INT32 &e)\r
204 {\r
205     CBC_OneDimWriter::RenderResult(encodedContents(contents), code, codeLength, isDevice, e);\r
206 }\r