1 // Copyright 2017 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 
7 #include "xfa/fxfa/parser/cxfa_barcode.h"
8 
9 #include "fxjs/xfa/cjx_node.h"
10 #include "third_party/base/ptr_util.h"
11 #include "xfa/fxfa/parser/cxfa_measurement.h"
12 
13 namespace {
14 
15 const CXFA_Node::AttributeData kBarcodeAttributeData[] = {
16     {XFA_Attribute::Id, XFA_AttributeType::CData, nullptr},
17     {XFA_Attribute::DataRowCount, XFA_AttributeType::CData, nullptr},
18     {XFA_Attribute::Use, XFA_AttributeType::CData, nullptr},
19     {XFA_Attribute::DataPrep, XFA_AttributeType::Enum,
20      (void*)XFA_AttributeValue::None},
21     {XFA_Attribute::Type, XFA_AttributeType::CData, (void*)nullptr},
22     {XFA_Attribute::TextLocation, XFA_AttributeType::Enum,
23      (void*)XFA_AttributeValue::Below},
24     {XFA_Attribute::ModuleWidth, XFA_AttributeType::Measure, (void*)L"0.25mm"},
25     {XFA_Attribute::PrintCheckDigit, XFA_AttributeType::Boolean, (void*)0},
26     {XFA_Attribute::ModuleHeight, XFA_AttributeType::Measure, (void*)L"5mm"},
27     {XFA_Attribute::StartChar, XFA_AttributeType::CData, nullptr},
28     {XFA_Attribute::Truncate, XFA_AttributeType::Boolean, (void*)0},
29     {XFA_Attribute::WideNarrowRatio, XFA_AttributeType::CData, (void*)L"3:1"},
30     {XFA_Attribute::ErrorCorrectionLevel, XFA_AttributeType::CData, nullptr},
31     {XFA_Attribute::UpsMode, XFA_AttributeType::Enum,
32      (void*)XFA_AttributeValue::UsCarrier},
33     {XFA_Attribute::Checksum, XFA_AttributeType::Enum,
34      (void*)XFA_AttributeValue::None},
35     {XFA_Attribute::CharEncoding, XFA_AttributeType::CData, (void*)L"UTF-8"},
36     {XFA_Attribute::Usehref, XFA_AttributeType::CData, nullptr},
37     {XFA_Attribute::DataColumnCount, XFA_AttributeType::CData, nullptr},
38     {XFA_Attribute::RowColumnRatio, XFA_AttributeType::CData, nullptr},
39     {XFA_Attribute::DataLength, XFA_AttributeType::CData, nullptr},
40     {XFA_Attribute::EndChar, XFA_AttributeType::CData, nullptr},
41 };
42 
43 }  // namespace
44 
CXFA_Barcode(CXFA_Document * doc,XFA_PacketType packet)45 CXFA_Barcode::CXFA_Barcode(CXFA_Document* doc, XFA_PacketType packet)
46     : CXFA_Node(doc,
47                 packet,
48                 (XFA_XDPPACKET_Template | XFA_XDPPACKET_Form),
49                 XFA_ObjectType::Node,
50                 XFA_Element::Barcode,
51                 {},
52                 kBarcodeAttributeData,
53                 pdfium::MakeUnique<CJX_Node>(this)) {}
54 
55 CXFA_Barcode::~CXFA_Barcode() = default;
56 
GetDefaultFFWidgetType() const57 XFA_FFWidgetType CXFA_Barcode::GetDefaultFFWidgetType() const {
58   return XFA_FFWidgetType::kBarcode;
59 }
60 
GetBarcodeType()61 WideString CXFA_Barcode::GetBarcodeType() {
62   return WideString(JSObject()->GetCData(XFA_Attribute::Type));
63 }
64 
GetCharEncoding()65 Optional<WideString> CXFA_Barcode::GetCharEncoding() {
66   return JSObject()->TryCData(XFA_Attribute::CharEncoding, true);
67 }
68 
GetChecksum()69 Optional<bool> CXFA_Barcode::GetChecksum() {
70   Optional<XFA_AttributeValue> checksum =
71       JSObject()->TryEnum(XFA_Attribute::Checksum, true);
72   if (!checksum)
73     return {};
74 
75   switch (*checksum) {
76     case XFA_AttributeValue::None:
77       return {false};
78     case XFA_AttributeValue::Auto:
79       return {true};
80     case XFA_AttributeValue::Checksum_1mod10:
81     case XFA_AttributeValue::Checksum_1mod10_1mod11:
82     case XFA_AttributeValue::Checksum_2mod10:
83     default:
84       break;
85   }
86   return {};
87 }
88 
GetDataLength()89 Optional<int32_t> CXFA_Barcode::GetDataLength() {
90   Optional<WideString> wsDataLength =
91       JSObject()->TryCData(XFA_Attribute::DataLength, true);
92   if (!wsDataLength)
93     return {};
94 
95   return {FXSYS_wtoi(wsDataLength->c_str())};
96 }
97 
GetStartChar()98 Optional<char> CXFA_Barcode::GetStartChar() {
99   Optional<WideString> wsStartEndChar =
100       JSObject()->TryCData(XFA_Attribute::StartChar, true);
101   if (!wsStartEndChar || wsStartEndChar->IsEmpty())
102     return {};
103 
104   return {static_cast<char>((*wsStartEndChar)[0])};
105 }
106 
GetEndChar()107 Optional<char> CXFA_Barcode::GetEndChar() {
108   Optional<WideString> wsStartEndChar =
109       JSObject()->TryCData(XFA_Attribute::EndChar, true);
110   if (!wsStartEndChar || wsStartEndChar->IsEmpty())
111     return {};
112 
113   return {static_cast<char>((*wsStartEndChar)[0])};
114 }
115 
GetECLevel()116 Optional<int32_t> CXFA_Barcode::GetECLevel() {
117   Optional<WideString> wsECLevel =
118       JSObject()->TryCData(XFA_Attribute::ErrorCorrectionLevel, true);
119   if (!wsECLevel)
120     return {};
121   return {FXSYS_wtoi(wsECLevel->c_str())};
122 }
123 
GetModuleWidth()124 Optional<int32_t> CXFA_Barcode::GetModuleWidth() {
125   Optional<CXFA_Measurement> moduleWidthHeight =
126       JSObject()->TryMeasure(XFA_Attribute::ModuleWidth, true);
127   if (!moduleWidthHeight)
128     return {};
129 
130   return {static_cast<int32_t>(moduleWidthHeight->ToUnit(XFA_Unit::Pt))};
131 }
132 
GetModuleHeight()133 Optional<int32_t> CXFA_Barcode::GetModuleHeight() {
134   Optional<CXFA_Measurement> moduleWidthHeight =
135       JSObject()->TryMeasure(XFA_Attribute::ModuleHeight, true);
136   if (!moduleWidthHeight)
137     return {};
138 
139   return {static_cast<int32_t>(moduleWidthHeight->ToUnit(XFA_Unit::Pt))};
140 }
141 
GetPrintChecksum()142 Optional<bool> CXFA_Barcode::GetPrintChecksum() {
143   return JSObject()->TryBoolean(XFA_Attribute::PrintCheckDigit, true);
144 }
145 
GetTextLocation()146 Optional<XFA_AttributeValue> CXFA_Barcode::GetTextLocation() {
147   return JSObject()->TryEnum(XFA_Attribute::TextLocation, true);
148 }
149 
GetTruncate()150 Optional<bool> CXFA_Barcode::GetTruncate() {
151   return JSObject()->TryBoolean(XFA_Attribute::Truncate, true);
152 }
153 
GetWideNarrowRatio()154 Optional<int8_t> CXFA_Barcode::GetWideNarrowRatio() {
155   Optional<WideString> wsWideNarrowRatio =
156       JSObject()->TryCData(XFA_Attribute::WideNarrowRatio, true);
157   if (!wsWideNarrowRatio)
158     return {};
159 
160   Optional<size_t> ptPos = wsWideNarrowRatio->Find(':');
161   if (!ptPos)
162     return {static_cast<int8_t>(FXSYS_wtoi(wsWideNarrowRatio->c_str()))};
163 
164   int32_t fB = FXSYS_wtoi(
165       wsWideNarrowRatio->Last(wsWideNarrowRatio->GetLength() - (*ptPos + 1))
166           .c_str());
167   if (!fB)
168     return {0};
169 
170   int32_t fA = FXSYS_wtoi(wsWideNarrowRatio->First(*ptPos).c_str());
171   float result = static_cast<float>(fA) / static_cast<float>(fB);
172   return {static_cast<int8_t>(result)};
173 }
174