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