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