1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 // Original code is licensed as follows: 7 /* 8 * Copyright 2011 ZXing authors 9 * 10 * Licensed under the Apache License, Version 2.0 (the "License"); 11 * you may not use this file except in compliance with the License. 12 * You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, software 17 * distributed under the License is distributed on an "AS IS" BASIS, 18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 * See the License for the specific language governing permissions and 20 * limitations under the License. 21 */ 22 23 #include "xfa/src/fxbarcode/barcode.h" 24 #include "xfa/src/fxbarcode/BC_Writer.h" 25 #include "xfa/src/fxbarcode/BC_Reader.h" 26 #include "xfa/src/fxbarcode/common/BC_CommonBitMatrix.h" 27 #include "xfa/src/fxbarcode/common/BC_CommonBitArray.h" 28 #include "BC_OneDReader.h" 29 #include "BC_OneDimWriter.h" 30 #include "BC_OnedCodaBarReader.h" 31 #include "BC_OnedCodaBarWriter.h" 32 const FX_CHAR CBC_OnedCodaBarWriter::START_END_CHARS[] = { 33 'A', 'B', 'C', 'D', 'T', 'N', '*', 'E', 'a', 'b', 'c', 'd', 't', 'n', 'e'}; 34 const FX_CHAR CBC_OnedCodaBarWriter::CONTENT_CHARS[] = { 35 '0', '1', '2', '3', '4', '5', '6', '7', 36 '8', '9', '-', '$', '/', ':', '+', '.'}; 37 CBC_OnedCodaBarWriter::CBC_OnedCodaBarWriter() { 38 m_chStart = 'A'; 39 m_chEnd = 'B'; 40 m_iWideNarrRatio = 2; 41 } 42 CBC_OnedCodaBarWriter::~CBC_OnedCodaBarWriter() {} 43 FX_BOOL CBC_OnedCodaBarWriter::SetStartChar(FX_CHAR start) { 44 for (int32_t i = 0; i < sizeof(START_END_CHARS) / sizeof(FX_CHAR); i++) { 45 if (START_END_CHARS[i] == start) { 46 m_chStart = start; 47 return TRUE; 48 } 49 } 50 return FALSE; 51 } 52 FX_BOOL CBC_OnedCodaBarWriter::SetEndChar(FX_CHAR end) { 53 for (int32_t i = 0; i < sizeof(START_END_CHARS) / sizeof(FX_CHAR); i++) { 54 if (START_END_CHARS[i] == end) { 55 m_chEnd = end; 56 return TRUE; 57 } 58 } 59 return FALSE; 60 } 61 void CBC_OnedCodaBarWriter::SetDataLength(int32_t length) { 62 m_iDataLenth = length + 2; 63 } 64 FX_BOOL CBC_OnedCodaBarWriter::SetTextLocation(BC_TEXT_LOC location) { 65 if (location < BC_TEXT_LOC_NONE || location > BC_TEXT_LOC_BELOWEMBED) { 66 return FALSE; 67 } 68 m_locTextLoc = location; 69 return TRUE; 70 } 71 FX_BOOL CBC_OnedCodaBarWriter::SetWideNarrowRatio(int32_t ratio) { 72 if (ratio < 2 || ratio > 3) { 73 return FALSE; 74 } 75 m_iWideNarrRatio = ratio; 76 return TRUE; 77 } 78 FX_BOOL CBC_OnedCodaBarWriter::FindChar(FX_WCHAR ch, FX_BOOL isContent) { 79 if (isContent) { 80 for (int32_t i = 0; i < sizeof(CONTENT_CHARS) / sizeof(FX_CHAR); i++) { 81 if (ch == (FX_WCHAR)CONTENT_CHARS[i]) { 82 return TRUE; 83 } 84 } 85 for (int32_t j = 0; j < sizeof(START_END_CHARS) / sizeof(FX_CHAR); j++) { 86 if (ch == (FX_WCHAR)START_END_CHARS[j]) { 87 return TRUE; 88 } 89 } 90 return FALSE; 91 } else { 92 for (int32_t i = 0; i < sizeof(CONTENT_CHARS) / sizeof(FX_CHAR); i++) { 93 if (ch == (FX_WCHAR)CONTENT_CHARS[i]) { 94 return TRUE; 95 } 96 } 97 return FALSE; 98 } 99 } 100 FX_BOOL CBC_OnedCodaBarWriter::CheckContentValidity( 101 const CFX_WideStringC& contents) { 102 FX_WCHAR ch; 103 int32_t index = 0; 104 for (index = 0; index < contents.GetLength(); index++) { 105 ch = contents.GetAt(index); 106 if (FindChar(ch, FALSE)) { 107 continue; 108 } else { 109 return FALSE; 110 } 111 } 112 return TRUE; 113 } 114 CFX_WideString CBC_OnedCodaBarWriter::FilterContents( 115 const CFX_WideStringC& contents) { 116 CFX_WideString filtercontents; 117 FX_WCHAR ch; 118 for (int32_t index = 0; index < contents.GetLength(); index++) { 119 ch = contents.GetAt(index); 120 if (ch > 175) { 121 index++; 122 continue; 123 } 124 if (FindChar(ch, TRUE)) { 125 filtercontents += ch; 126 } else { 127 continue; 128 } 129 } 130 return filtercontents; 131 } 132 uint8_t* CBC_OnedCodaBarWriter::Encode(const CFX_ByteString& contents, 133 BCFORMAT format, 134 int32_t& outWidth, 135 int32_t& outHeight, 136 int32_t& e) { 137 uint8_t* ret = Encode(contents, format, outWidth, outHeight, 0, e); 138 BC_EXCEPTION_CHECK_ReturnValue(e, NULL); 139 return ret; 140 } 141 uint8_t* CBC_OnedCodaBarWriter::Encode(const CFX_ByteString& contents, 142 BCFORMAT format, 143 int32_t& outWidth, 144 int32_t& outHeight, 145 int32_t hints, 146 int32_t& e) { 147 if (format != BCFORMAT_CODABAR) { 148 e = BCExceptionOnlyEncodeCODEBAR; 149 return NULL; 150 } 151 uint8_t* ret = 152 CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e); 153 BC_EXCEPTION_CHECK_ReturnValue(e, NULL); 154 return ret; 155 } 156 uint8_t* CBC_OnedCodaBarWriter::Encode(const CFX_ByteString& contents, 157 int32_t& outLength, 158 int32_t& e) { 159 CBC_OnedCodaBarReader CodaBarR; 160 CFX_ByteString data = m_chStart + contents + m_chEnd; 161 m_iContentLen = data.GetLength(); 162 uint8_t* result = FX_Alloc2D(uint8_t, m_iWideNarrRatio * 7, data.GetLength()); 163 FX_CHAR ch; 164 int32_t position = 0; 165 for (int32_t index = 0; index < data.GetLength(); index++) { 166 ch = data.GetAt(index); 167 if (((ch >= 'a') && (ch <= 'z'))) { 168 ch = ch - 32; 169 } 170 switch (ch) { 171 case 'T': 172 ch = 'A'; 173 break; 174 case 'N': 175 ch = 'B'; 176 break; 177 case '*': 178 ch = 'C'; 179 break; 180 case 'E': 181 ch = 'D'; 182 break; 183 default: 184 break; 185 } 186 int32_t code = 0; 187 int32_t len = (int32_t)strlen(CodaBarR.ALPHABET_STRING); 188 for (int32_t i = 0; i < len; i++) { 189 if (ch == CodaBarR.ALPHABET_STRING[i]) { 190 code = CodaBarR.CHARACTER_ENCODINGS[i]; 191 break; 192 } 193 } 194 uint8_t color = 1; 195 int32_t counter = 0; 196 int32_t bit = 0; 197 while (bit < 7) { 198 result[position] = color; 199 position++; 200 if (((code >> (6 - bit)) & 1) == 0 || counter == m_iWideNarrRatio - 1) { 201 color = !color; 202 bit++; 203 counter = 0; 204 } else { 205 counter++; 206 } 207 } 208 if (index < data.GetLength() - 1) { 209 result[position] = 0; 210 position++; 211 } 212 } 213 outLength = position; 214 return result; 215 } 216 CFX_WideString CBC_OnedCodaBarWriter::encodedContents( 217 const CFX_WideStringC& contents) { 218 CFX_WideString strStart(m_chStart); 219 CFX_WideString strEnd(m_chEnd); 220 return strStart + contents + strEnd; 221 } 222 void CBC_OnedCodaBarWriter::RenderResult(const CFX_WideStringC& contents, 223 uint8_t* code, 224 int32_t codeLength, 225 FX_BOOL isDevice, 226 int32_t& e) { 227 CBC_OneDimWriter::RenderResult(encodedContents(contents), code, codeLength, 228 isDevice, e); 229 } 230