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