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 
7 #include "xfa/fwl/cfwl_barcode.h"
8 
9 #include <utility>
10 
11 #include "fxbarcode/cfx_barcode.h"
12 #include "third_party/base/ptr_util.h"
13 #include "xfa/fgas/font/cfgas_gefont.h"
14 #include "xfa/fwl/cfwl_notedriver.h"
15 #include "xfa/fwl/cfwl_themepart.h"
16 #include "xfa/fwl/ifwl_themeprovider.h"
17 #include "xfa/fwl/theme/cfwl_utils.h"
18 
CFWL_Barcode(const CFWL_App * app)19 CFWL_Barcode::CFWL_Barcode(const CFWL_App* app)
20     : CFWL_Edit(app, pdfium::MakeUnique<CFWL_WidgetProperties>(), nullptr) {}
21 
22 CFWL_Barcode::~CFWL_Barcode() = default;
23 
GetClassID() const24 FWL_Type CFWL_Barcode::GetClassID() const {
25   return FWL_Type::Barcode;
26 }
27 
Update()28 void CFWL_Barcode::Update() {
29   if (IsLocked())
30     return;
31 
32   CFWL_Edit::Update();
33   GenerateBarcodeImageCache();
34 }
35 
DrawWidget(CXFA_Graphics * pGraphics,const CFX_Matrix & matrix)36 void CFWL_Barcode::DrawWidget(CXFA_Graphics* pGraphics,
37                               const CFX_Matrix& matrix) {
38   if (!pGraphics)
39     return;
40   if (!m_pProperties->m_pThemeProvider)
41     return;
42   if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
43     GenerateBarcodeImageCache();
44     if (!m_pBarcodeEngine || m_eStatus != Status::kEncodeSuccess)
45       return;
46 
47     CFX_Matrix mt;
48     mt.e = GetRTClient().left;
49     mt.f = GetRTClient().top;
50     mt.Concat(matrix);
51 
52     m_pBarcodeEngine->RenderDevice(pGraphics->GetRenderDevice(), &matrix);
53     return;
54   }
55   CFWL_Edit::DrawWidget(pGraphics, matrix);
56 }
57 
SetType(BC_TYPE type)58 void CFWL_Barcode::SetType(BC_TYPE type) {
59   if (m_type == type)
60     return;
61 
62   m_pBarcodeEngine.reset();
63   m_type = type;
64   m_eStatus = Status::kNeedUpdate;
65 }
66 
SetText(const WideString & wsText)67 void CFWL_Barcode::SetText(const WideString& wsText) {
68   m_pBarcodeEngine.reset();
69   m_eStatus = Status::kNeedUpdate;
70   CFWL_Edit::SetText(wsText);
71 }
72 
SetTextSkipNotify(const WideString & wsText)73 void CFWL_Barcode::SetTextSkipNotify(const WideString& wsText) {
74   m_pBarcodeEngine.reset();
75   m_eStatus = Status::kNeedUpdate;
76   CFWL_Edit::SetTextSkipNotify(wsText);
77 }
78 
IsProtectedType() const79 bool CFWL_Barcode::IsProtectedType() const {
80   if (!m_pBarcodeEngine)
81     return true;
82 
83   BC_TYPE tEngineType = m_pBarcodeEngine->GetType();
84   return tEngineType == BC_QR_CODE || tEngineType == BC_PDF417 ||
85          tEngineType == BC_DATAMATRIX;
86 }
87 
OnProcessEvent(CFWL_Event * pEvent)88 void CFWL_Barcode::OnProcessEvent(CFWL_Event* pEvent) {
89   if (pEvent->GetType() == CFWL_Event::Type::TextWillChange) {
90     m_pBarcodeEngine.reset();
91     m_eStatus = Status::kNeedUpdate;
92   }
93   CFWL_Edit::OnProcessEvent(pEvent);
94 }
95 
SetCharEncoding(BC_CHAR_ENCODING encoding)96 void CFWL_Barcode::SetCharEncoding(BC_CHAR_ENCODING encoding) {
97   m_dwAttributeMask |= FWL_BCDATTRIBUTE_CHARENCODING;
98   m_eCharEncoding = encoding;
99 }
100 
SetModuleHeight(int32_t height)101 void CFWL_Barcode::SetModuleHeight(int32_t height) {
102   m_dwAttributeMask |= FWL_BCDATTRIBUTE_MODULEHEIGHT;
103   m_nModuleHeight = height;
104 }
105 
SetModuleWidth(int32_t width)106 void CFWL_Barcode::SetModuleWidth(int32_t width) {
107   m_dwAttributeMask |= FWL_BCDATTRIBUTE_MODULEWIDTH;
108   m_nModuleWidth = width;
109 }
110 
SetDataLength(int32_t dataLength)111 void CFWL_Barcode::SetDataLength(int32_t dataLength) {
112   m_dwAttributeMask |= FWL_BCDATTRIBUTE_DATALENGTH;
113   m_nDataLength = dataLength;
114   SetLimit(dataLength);
115 }
116 
SetCalChecksum(bool calChecksum)117 void CFWL_Barcode::SetCalChecksum(bool calChecksum) {
118   m_dwAttributeMask |= FWL_BCDATTRIBUTE_CALCHECKSUM;
119   m_bCalChecksum = calChecksum;
120 }
121 
SetPrintChecksum(bool printChecksum)122 void CFWL_Barcode::SetPrintChecksum(bool printChecksum) {
123   m_dwAttributeMask |= FWL_BCDATTRIBUTE_PRINTCHECKSUM;
124   m_bPrintChecksum = printChecksum;
125 }
126 
SetTextLocation(BC_TEXT_LOC location)127 void CFWL_Barcode::SetTextLocation(BC_TEXT_LOC location) {
128   m_dwAttributeMask |= FWL_BCDATTRIBUTE_TEXTLOCATION;
129   m_eTextLocation = location;
130 }
131 
SetWideNarrowRatio(int8_t ratio)132 void CFWL_Barcode::SetWideNarrowRatio(int8_t ratio) {
133   m_dwAttributeMask |= FWL_BCDATTRIBUTE_WIDENARROWRATIO;
134   m_nWideNarrowRatio = ratio;
135 }
136 
SetStartChar(char startChar)137 void CFWL_Barcode::SetStartChar(char startChar) {
138   m_dwAttributeMask |= FWL_BCDATTRIBUTE_STARTCHAR;
139   m_cStartChar = startChar;
140 }
141 
SetEndChar(char endChar)142 void CFWL_Barcode::SetEndChar(char endChar) {
143   m_dwAttributeMask |= FWL_BCDATTRIBUTE_ENDCHAR;
144   m_cEndChar = endChar;
145 }
146 
SetErrorCorrectionLevel(int32_t ecLevel)147 void CFWL_Barcode::SetErrorCorrectionLevel(int32_t ecLevel) {
148   m_dwAttributeMask |= FWL_BCDATTRIBUTE_ECLEVEL;
149   m_nECLevel = ecLevel;
150 }
151 
GenerateBarcodeImageCache()152 void CFWL_Barcode::GenerateBarcodeImageCache() {
153   if (m_eStatus != Status::kNeedUpdate)
154     return;
155 
156   m_eStatus = Status::kNormal;
157   CreateBarcodeEngine();
158   if (!m_pBarcodeEngine)
159     return;
160 
161   IFWL_ThemeProvider* pTheme = GetAvailableTheme();
162   if (pTheme) {
163     CFWL_ThemePart part;
164     part.m_pWidget = this;
165     if (RetainPtr<CFGAS_GEFont> pFont = pTheme->GetFont(part)) {
166       if (CFX_Font* pCXFont = pFont->GetDevFont())
167         m_pBarcodeEngine->SetFont(pCXFont);
168     }
169     m_pBarcodeEngine->SetFontSize(pTheme->GetFontSize(part));
170     m_pBarcodeEngine->SetFontColor(pTheme->GetTextColor(part));
171   } else {
172     m_pBarcodeEngine->SetFontSize(FWLTHEME_CAPACITY_FontSize);
173   }
174 
175   m_pBarcodeEngine->SetHeight(int32_t(GetRTClient().height));
176   m_pBarcodeEngine->SetWidth(int32_t(GetRTClient().width));
177   if (m_dwAttributeMask & FWL_BCDATTRIBUTE_CHARENCODING)
178     m_pBarcodeEngine->SetCharEncoding(m_eCharEncoding);
179   if (m_dwAttributeMask & FWL_BCDATTRIBUTE_MODULEHEIGHT)
180     m_pBarcodeEngine->SetModuleHeight(m_nModuleHeight);
181   if (m_dwAttributeMask & FWL_BCDATTRIBUTE_MODULEWIDTH)
182     m_pBarcodeEngine->SetModuleWidth(m_nModuleWidth);
183   if (m_dwAttributeMask & FWL_BCDATTRIBUTE_DATALENGTH)
184     m_pBarcodeEngine->SetDataLength(m_nDataLength);
185   if (m_dwAttributeMask & FWL_BCDATTRIBUTE_CALCHECKSUM)
186     m_pBarcodeEngine->SetCalChecksum(m_bCalChecksum);
187   if (m_dwAttributeMask & FWL_BCDATTRIBUTE_PRINTCHECKSUM)
188     m_pBarcodeEngine->SetPrintChecksum(m_bPrintChecksum);
189   if (m_dwAttributeMask & FWL_BCDATTRIBUTE_TEXTLOCATION)
190     m_pBarcodeEngine->SetTextLocation(m_eTextLocation);
191   if (m_dwAttributeMask & FWL_BCDATTRIBUTE_WIDENARROWRATIO)
192     m_pBarcodeEngine->SetWideNarrowRatio(m_nWideNarrowRatio);
193   if (m_dwAttributeMask & FWL_BCDATTRIBUTE_STARTCHAR)
194     m_pBarcodeEngine->SetStartChar(m_cStartChar);
195   if (m_dwAttributeMask & FWL_BCDATTRIBUTE_ENDCHAR)
196     m_pBarcodeEngine->SetEndChar(m_cEndChar);
197   if (m_dwAttributeMask & FWL_BCDATTRIBUTE_ECLEVEL)
198     m_pBarcodeEngine->SetErrorCorrectionLevel(m_nECLevel);
199 
200   m_eStatus = m_pBarcodeEngine->Encode(GetText().AsStringView())
201                   ? Status::kEncodeSuccess
202                   : Status::kNormal;
203 }
204 
CreateBarcodeEngine()205 void CFWL_Barcode::CreateBarcodeEngine() {
206   if (m_pBarcodeEngine || m_type == BC_UNKNOWN)
207     return;
208 
209   m_pBarcodeEngine = CFX_Barcode::Create(m_type);
210 }
211