|  | // Copyright 2014 The PDFium Authors | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 
|  | // Original code is licensed as follows: | 
|  | /* | 
|  | * Copyright 2010 ZXing authors | 
|  | * | 
|  | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | * you may not use this file except in compliance with the License. | 
|  | * You may obtain a copy of the License at | 
|  | * | 
|  | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, software | 
|  | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | * See the License for the specific language governing permissions and | 
|  | * limitations under the License. | 
|  | */ | 
|  |  | 
|  | #include "fxbarcode/oned/BC_OnedCode128Writer.h" | 
|  |  | 
|  | #include <ctype.h> | 
|  |  | 
|  | #include <memory> | 
|  |  | 
|  | #include "core/fxcrt/check.h" | 
|  | #include "core/fxcrt/fx_memory_wrappers.h" | 
|  | #include "fxbarcode/BC_Writer.h" | 
|  | #include "fxbarcode/oned/BC_OneDimWriter.h" | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | constexpr size_t kPatternSize = 7; | 
|  |  | 
|  | const uint8_t kCodePatterns[107][kPatternSize] = { | 
|  | {2, 1, 2, 2, 2, 2, 0}, {2, 2, 2, 1, 2, 2, 0}, {2, 2, 2, 2, 2, 1, 0}, | 
|  | {1, 2, 1, 2, 2, 3, 0}, {1, 2, 1, 3, 2, 2, 0}, {1, 3, 1, 2, 2, 2, 0}, | 
|  | {1, 2, 2, 2, 1, 3, 0}, {1, 2, 2, 3, 1, 2, 0}, {1, 3, 2, 2, 1, 2, 0}, | 
|  | {2, 2, 1, 2, 1, 3, 0}, {2, 2, 1, 3, 1, 2, 0}, {2, 3, 1, 2, 1, 2, 0}, | 
|  | {1, 1, 2, 2, 3, 2, 0}, {1, 2, 2, 1, 3, 2, 0}, {1, 2, 2, 2, 3, 1, 0}, | 
|  | {1, 1, 3, 2, 2, 2, 0}, {1, 2, 3, 1, 2, 2, 0}, {1, 2, 3, 2, 2, 1, 0}, | 
|  | {2, 2, 3, 2, 1, 1, 0}, {2, 2, 1, 1, 3, 2, 0}, {2, 2, 1, 2, 3, 1, 0}, | 
|  | {2, 1, 3, 2, 1, 2, 0}, {2, 2, 3, 1, 1, 2, 0}, {3, 1, 2, 1, 3, 1, 0}, | 
|  | {3, 1, 1, 2, 2, 2, 0}, {3, 2, 1, 1, 2, 2, 0}, {3, 2, 1, 2, 2, 1, 0}, | 
|  | {3, 1, 2, 2, 1, 2, 0}, {3, 2, 2, 1, 1, 2, 0}, {3, 2, 2, 2, 1, 1, 0}, | 
|  | {2, 1, 2, 1, 2, 3, 0}, {2, 1, 2, 3, 2, 1, 0}, {2, 3, 2, 1, 2, 1, 0}, | 
|  | {1, 1, 1, 3, 2, 3, 0}, {1, 3, 1, 1, 2, 3, 0}, {1, 3, 1, 3, 2, 1, 0}, | 
|  | {1, 1, 2, 3, 1, 3, 0}, {1, 3, 2, 1, 1, 3, 0}, {1, 3, 2, 3, 1, 1, 0}, | 
|  | {2, 1, 1, 3, 1, 3, 0}, {2, 3, 1, 1, 1, 3, 0}, {2, 3, 1, 3, 1, 1, 0}, | 
|  | {1, 1, 2, 1, 3, 3, 0}, {1, 1, 2, 3, 3, 1, 0}, {1, 3, 2, 1, 3, 1, 0}, | 
|  | {1, 1, 3, 1, 2, 3, 0}, {1, 1, 3, 3, 2, 1, 0}, {1, 3, 3, 1, 2, 1, 0}, | 
|  | {3, 1, 3, 1, 2, 1, 0}, {2, 1, 1, 3, 3, 1, 0}, {2, 3, 1, 1, 3, 1, 0}, | 
|  | {2, 1, 3, 1, 1, 3, 0}, {2, 1, 3, 3, 1, 1, 0}, {2, 1, 3, 1, 3, 1, 0}, | 
|  | {3, 1, 1, 1, 2, 3, 0}, {3, 1, 1, 3, 2, 1, 0}, {3, 3, 1, 1, 2, 1, 0}, | 
|  | {3, 1, 2, 1, 1, 3, 0}, {3, 1, 2, 3, 1, 1, 0}, {3, 3, 2, 1, 1, 1, 0}, | 
|  | {3, 1, 4, 1, 1, 1, 0}, {2, 2, 1, 4, 1, 1, 0}, {4, 3, 1, 1, 1, 1, 0}, | 
|  | {1, 1, 1, 2, 2, 4, 0}, {1, 1, 1, 4, 2, 2, 0}, {1, 2, 1, 1, 2, 4, 0}, | 
|  | {1, 2, 1, 4, 2, 1, 0}, {1, 4, 1, 1, 2, 2, 0}, {1, 4, 1, 2, 2, 1, 0}, | 
|  | {1, 1, 2, 2, 1, 4, 0}, {1, 1, 2, 4, 1, 2, 0}, {1, 2, 2, 1, 1, 4, 0}, | 
|  | {1, 2, 2, 4, 1, 1, 0}, {1, 4, 2, 1, 1, 2, 0}, {1, 4, 2, 2, 1, 1, 0}, | 
|  | {2, 4, 1, 2, 1, 1, 0}, {2, 2, 1, 1, 1, 4, 0}, {4, 1, 3, 1, 1, 1, 0}, | 
|  | {2, 4, 1, 1, 1, 2, 0}, {1, 3, 4, 1, 1, 1, 0}, {1, 1, 1, 2, 4, 2, 0}, | 
|  | {1, 2, 1, 1, 4, 2, 0}, {1, 2, 1, 2, 4, 1, 0}, {1, 1, 4, 2, 1, 2, 0}, | 
|  | {1, 2, 4, 1, 1, 2, 0}, {1, 2, 4, 2, 1, 1, 0}, {4, 1, 1, 2, 1, 2, 0}, | 
|  | {4, 2, 1, 1, 1, 2, 0}, {4, 2, 1, 2, 1, 1, 0}, {2, 1, 2, 1, 4, 1, 0}, | 
|  | {2, 1, 4, 1, 2, 1, 0}, {4, 1, 2, 1, 2, 1, 0}, {1, 1, 1, 1, 4, 3, 0}, | 
|  | {1, 1, 1, 3, 4, 1, 0}, {1, 3, 1, 1, 4, 1, 0}, {1, 1, 4, 1, 1, 3, 0}, | 
|  | {1, 1, 4, 3, 1, 1, 0}, {4, 1, 1, 1, 1, 3, 0}, {4, 1, 1, 3, 1, 1, 0}, | 
|  | {1, 1, 3, 1, 4, 1, 0}, {1, 1, 4, 1, 3, 1, 0}, {3, 1, 1, 1, 4, 1, 0}, | 
|  | {4, 1, 1, 1, 3, 1, 0}, {2, 1, 1, 4, 1, 2, 0}, {2, 1, 1, 2, 1, 4, 0}, | 
|  | {2, 1, 1, 2, 3, 2, 0}, {2, 3, 3, 1, 1, 1, 2}}; | 
|  |  | 
|  | const int32_t CODE_START_B = 104; | 
|  | const int32_t CODE_START_C = 105; | 
|  | const int32_t CODE_STOP = 106; | 
|  |  | 
|  | bool IsInOnedCode128Alphabet(wchar_t ch) { | 
|  | int32_t index = static_cast<int32_t>(ch); | 
|  | return index >= 32 && index <= 126 && index != 34; | 
|  | } | 
|  |  | 
|  | }  // namespace | 
|  |  | 
|  | CBC_OnedCode128Writer::CBC_OnedCode128Writer(BC_TYPE type) | 
|  | : m_codeFormat(type) { | 
|  | DCHECK(m_codeFormat == BC_TYPE::kCode128B || | 
|  | m_codeFormat == BC_TYPE::kCode128C); | 
|  | } | 
|  |  | 
|  | CBC_OnedCode128Writer::~CBC_OnedCode128Writer() = default; | 
|  |  | 
|  | bool CBC_OnedCode128Writer::CheckContentValidity(WideStringView contents) { | 
|  | return HasValidContentSize(contents) && | 
|  | std::all_of(contents.begin(), contents.end(), IsInOnedCode128Alphabet); | 
|  | } | 
|  |  | 
|  | WideString CBC_OnedCode128Writer::FilterContents(WideStringView contents) { | 
|  | const wchar_t limit = m_codeFormat == BC_TYPE::kCode128B ? 126 : 106; | 
|  |  | 
|  | WideString filtered; | 
|  | filtered.Reserve(contents.GetLength()); | 
|  | for (size_t i = 0; i < contents.GetLength(); i++) { | 
|  | wchar_t ch = contents[i]; | 
|  | if (ch > 175) { | 
|  | i++; | 
|  | continue; | 
|  | } | 
|  | if (ch >= 32 && ch <= limit) | 
|  | filtered += ch; | 
|  | } | 
|  | return filtered; | 
|  | } | 
|  |  | 
|  | void CBC_OnedCode128Writer::SetTextLocation(BC_TEXT_LOC location) { | 
|  | m_locTextLoc = location; | 
|  | } | 
|  |  | 
|  | DataVector<uint8_t> CBC_OnedCode128Writer::Encode(const ByteString& contents) { | 
|  | if (contents.GetLength() < 1 || contents.GetLength() > 80) | 
|  | return DataVector<uint8_t>(); | 
|  |  | 
|  | std::vector<int32_t> patterns; | 
|  | int32_t checkSum = 0; | 
|  | if (m_codeFormat == BC_TYPE::kCode128B) | 
|  | checkSum = Encode128B(contents, &patterns); | 
|  | else | 
|  | checkSum = Encode128C(contents, &patterns); | 
|  |  | 
|  | checkSum %= 103; | 
|  | patterns.push_back(checkSum); | 
|  | patterns.push_back(CODE_STOP); | 
|  | m_iContentLen = contents.GetLength() + 3; | 
|  | int32_t codeWidth = 0; | 
|  | for (const auto& patternIndex : patterns) { | 
|  | const uint8_t* pattern = kCodePatterns[patternIndex]; | 
|  | for (size_t i = 0; i < kPatternSize; ++i) | 
|  | codeWidth += pattern[i]; | 
|  | } | 
|  | DataVector<uint8_t> result(codeWidth); | 
|  | auto result_span = pdfium::make_span(result); | 
|  | for (const int32_t pattern_index : patterns) { | 
|  | const uint8_t* pattern = kCodePatterns[pattern_index]; | 
|  | result_span = AppendPattern(result_span, {pattern, kPatternSize}, true); | 
|  | } | 
|  | return result; | 
|  | } | 
|  |  | 
|  | // static | 
|  | int32_t CBC_OnedCode128Writer::Encode128B(const ByteString& contents, | 
|  | std::vector<int32_t>* patterns) { | 
|  | int32_t checkWeight = 1; | 
|  | patterns->push_back(CODE_START_B); | 
|  | int32_t checkSum = CODE_START_B * checkWeight; | 
|  | for (size_t position = 0; position < contents.GetLength(); position++) { | 
|  | int32_t patternIndex = contents[position] - ' '; | 
|  | patterns->push_back(patternIndex); | 
|  | checkSum += patternIndex * checkWeight++; | 
|  | } | 
|  | return checkSum; | 
|  | } | 
|  |  | 
|  | // static | 
|  | int32_t CBC_OnedCode128Writer::Encode128C(const ByteString& contents, | 
|  | std::vector<int32_t>* patterns) { | 
|  | int32_t checkWeight = 1; | 
|  | patterns->push_back(CODE_START_C); | 
|  | int32_t checkSum = CODE_START_C * checkWeight; | 
|  | size_t position = 0; | 
|  | while (position < contents.GetLength()) { | 
|  | int32_t patternIndex; | 
|  | char ch = contents[position]; | 
|  | if (isdigit(ch)) { | 
|  | patternIndex = FXSYS_atoi( | 
|  | contents.Substr(position, contents.IsValidIndex(position + 1) ? 2 : 1) | 
|  | .c_str()); | 
|  | ++position; | 
|  | if (position < contents.GetLength() && isdigit(contents[position])) | 
|  | ++position; | 
|  | } else { | 
|  | patternIndex = static_cast<int32_t>(ch); | 
|  | ++position; | 
|  | } | 
|  | patterns->push_back(patternIndex); | 
|  | checkSum += patternIndex * checkWeight++; | 
|  | } | 
|  | return checkSum; | 
|  | } |