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 2010 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 "fxbarcode/oned/BC_OnedUPCAWriter.h"
24 
25 #include <vector>
26 
27 #include "core/fxcrt/fx_extension.h"
28 #include "core/fxge/cfx_defaultrenderdevice.h"
29 #include "fxbarcode/BC_Writer.h"
30 #include "fxbarcode/oned/BC_OneDimWriter.h"
31 #include "fxbarcode/oned/BC_OnedEAN13Writer.h"
32 #include "third_party/base/ptr_util.h"
33 
CBC_OnedUPCAWriter()34 CBC_OnedUPCAWriter::CBC_OnedUPCAWriter() {
35   m_bLeftPadding = true;
36   m_bRightPadding = true;
37 }
38 
Init()39 void CBC_OnedUPCAWriter::Init() {
40   m_subWriter = pdfium::MakeUnique<CBC_OnedEAN13Writer>();
41 }
42 
~CBC_OnedUPCAWriter()43 CBC_OnedUPCAWriter::~CBC_OnedUPCAWriter() {}
44 
CheckContentValidity(const WideStringView & contents)45 bool CBC_OnedUPCAWriter::CheckContentValidity(const WideStringView& contents) {
46   for (size_t i = 0; i < contents.GetLength(); ++i) {
47     if (contents[i] < '0' || contents[i] > '9')
48       return false;
49   }
50   return true;
51 }
52 
FilterContents(const WideStringView & contents)53 WideString CBC_OnedUPCAWriter::FilterContents(const WideStringView& contents) {
54   WideString filtercontents;
55   wchar_t ch;
56   for (size_t i = 0; i < contents.GetLength(); i++) {
57     ch = contents[i];
58     if (ch > 175) {
59       i++;
60       continue;
61     }
62     if (ch >= '0' && ch <= '9') {
63       filtercontents += ch;
64     }
65   }
66   return filtercontents;
67 }
68 
CalcChecksum(const ByteString & contents)69 int32_t CBC_OnedUPCAWriter::CalcChecksum(const ByteString& contents) {
70   int32_t odd = 0;
71   int32_t even = 0;
72   size_t j = 1;
73   for (size_t i = contents.GetLength(); i > 0; i--) {
74     if (j % 2) {
75       odd += FXSYS_DecimalCharToInt(contents[i - 1]);
76     } else {
77       even += FXSYS_DecimalCharToInt(contents[i - 1]);
78     }
79     j++;
80   }
81   int32_t checksum = (odd * 3 + even) % 10;
82   checksum = (10 - checksum) % 10;
83   return checksum;
84 }
85 
EncodeWithHint(const ByteString & contents,BCFORMAT format,int32_t & outWidth,int32_t & outHeight,int32_t hints)86 uint8_t* CBC_OnedUPCAWriter::EncodeWithHint(const ByteString& contents,
87                                             BCFORMAT format,
88                                             int32_t& outWidth,
89                                             int32_t& outHeight,
90                                             int32_t hints) {
91   if (format != BCFORMAT_UPC_A)
92     return nullptr;
93 
94   ByteString toEAN13String = '0' + contents;
95   m_iDataLenth = 13;
96   return m_subWriter->EncodeWithHint(toEAN13String, BCFORMAT_EAN_13, outWidth,
97                                      outHeight, hints);
98 }
99 
EncodeImpl(const ByteString & contents,int32_t & outLength)100 uint8_t* CBC_OnedUPCAWriter::EncodeImpl(const ByteString& contents,
101                                         int32_t& outLength) {
102   return nullptr;
103 }
104 
ShowChars(const WideStringView & contents,CFX_RenderDevice * device,const CFX_Matrix * matrix,int32_t barWidth,int32_t multiple)105 bool CBC_OnedUPCAWriter::ShowChars(const WideStringView& contents,
106                                    CFX_RenderDevice* device,
107                                    const CFX_Matrix* matrix,
108                                    int32_t barWidth,
109                                    int32_t multiple) {
110   if (!device)
111     return false;
112 
113   int32_t leftPadding = 7 * multiple;
114   int32_t leftPosition = 10 * multiple + leftPadding;
115   ByteString str = FX_UTF8Encode(contents);
116   int32_t iLen = str.GetLength();
117   std::vector<FXTEXT_CHARPOS> charpos(iLen);
118   ByteString tempStr = str.Mid(1, 5);
119   float strWidth = (float)35 * multiple;
120   float blank = 0.0;
121 
122   iLen = tempStr.GetLength();
123   int32_t iFontSize = (int32_t)fabs(m_fFontSize);
124   int32_t iTextHeight = iFontSize + 1;
125 
126   CFX_Matrix matr(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0);
127   CFX_FloatRect rect((float)leftPosition, (float)(m_Height - iTextHeight),
128                      (float)(leftPosition + strWidth - 0.5), (float)m_Height);
129   matr.Concat(*matrix);
130   FX_RECT re = matr.TransformRect(rect).GetOuterRect();
131   device->FillRect(&re, m_backgroundColor);
132   CFX_Matrix matr1(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0);
133   CFX_FloatRect rect1((float)(leftPosition + 40 * multiple),
134                       (float)(m_Height - iTextHeight),
135                       (float)((leftPosition + 40 * multiple) + strWidth - 0.5),
136                       (float)m_Height);
137   matr1.Concat(*matrix);
138   re = matr1.TransformRect(rect1).GetOuterRect();
139   device->FillRect(&re, m_backgroundColor);
140   float strWidth1 = (float)multiple * 7;
141   CFX_Matrix matr2(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0);
142   CFX_FloatRect rect2(0.0, (float)(m_Height - iTextHeight),
143                       (float)strWidth1 - 1, (float)m_Height);
144   matr2.Concat(*matrix);
145   re = matr2.TransformRect(rect2).GetOuterRect();
146   device->FillRect(&re, m_backgroundColor);
147   CFX_Matrix matr3(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0);
148   CFX_FloatRect rect3((float)(leftPosition + 85 * multiple),
149                       (float)(m_Height - iTextHeight),
150                       (float)((leftPosition + 85 * multiple) + strWidth1 - 0.5),
151                       (float)m_Height);
152   matr3.Concat(*matrix);
153   re = matr3.TransformRect(rect3).GetOuterRect();
154   device->FillRect(&re, m_backgroundColor);
155   strWidth = strWidth * m_outputHScale;
156 
157   CalcTextInfo(tempStr, &charpos[1], m_pFont.Get(), strWidth, iFontSize, blank);
158   {
159     CFX_Matrix affine_matrix1(1.0, 0.0, 0.0, -1.0,
160                               (float)leftPosition * m_outputHScale,
161                               (float)(m_Height - iTextHeight + iFontSize));
162     if (matrix)
163       affine_matrix1.Concat(*matrix);
164     device->DrawNormalText(iLen, &charpos[1], m_pFont.Get(),
165                            static_cast<float>(iFontSize), &affine_matrix1,
166                            m_fontColor, FXTEXT_CLEARTYPE);
167   }
168   tempStr = str.Mid(6, 5);
169   iLen = tempStr.GetLength();
170   CalcTextInfo(tempStr, &charpos[6], m_pFont.Get(), strWidth, iFontSize, blank);
171   {
172     CFX_Matrix affine_matrix1(
173         1.0, 0.0, 0.0, -1.0,
174         (float)(leftPosition + 40 * multiple) * m_outputHScale,
175         (float)(m_Height - iTextHeight + iFontSize));
176     if (matrix)
177       affine_matrix1.Concat(*matrix);
178     device->DrawNormalText(iLen, &charpos[6], m_pFont.Get(),
179                            static_cast<float>(iFontSize), &affine_matrix1,
180                            m_fontColor, FXTEXT_CLEARTYPE);
181   }
182   tempStr = str.Left(1);
183   iLen = tempStr.GetLength();
184   strWidth = (float)multiple * 7;
185   strWidth = strWidth * m_outputHScale;
186 
187   CalcTextInfo(tempStr, charpos.data(), m_pFont.Get(), strWidth, iFontSize,
188                blank);
189   {
190     CFX_Matrix affine_matrix1(1.0, 0.0, 0.0, -1.0, 0,
191                               (float)(m_Height - iTextHeight + iFontSize));
192     if (matrix)
193       affine_matrix1.Concat(*matrix);
194     device->DrawNormalText(iLen, charpos.data(), m_pFont.Get(),
195                            static_cast<float>(iFontSize), &affine_matrix1,
196                            m_fontColor, FXTEXT_CLEARTYPE);
197   }
198   tempStr = str.Mid(11, 1);
199   iLen = tempStr.GetLength();
200   CalcTextInfo(tempStr, &charpos[11], m_pFont.Get(), strWidth, iFontSize,
201                blank);
202   {
203     CFX_Matrix affine_matrix1(
204         1.0, 0.0, 0.0, -1.0,
205         (float)(leftPosition + 85 * multiple) * m_outputHScale,
206         (float)(m_Height - iTextHeight + iFontSize));
207     if (matrix)
208       affine_matrix1.Concat(*matrix);
209     device->DrawNormalText(iLen, &charpos[11], m_pFont.Get(),
210                            static_cast<float>(iFontSize), &affine_matrix1,
211                            m_fontColor, FXTEXT_CLEARTYPE);
212   }
213   return true;
214 }
215