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/src/foxitlib.h"
8#include "xfa/src/fwl/src/core/include/fwl_targetimp.h"
9#include "xfa/src/fwl/src/core/include/fwl_noteimp.h"
10#include "xfa/src/fwl/src/core/include/fwl_widgetimp.h"
11#include "xfa/src/fwl/src/basewidget/include/fwl_editimp.h"
12#include "xfa/src/fwl/src/basewidget/include/fwl_barcodeimp.h"
13
14// static
15IFWL_Barcode* IFWL_Barcode::Create(const CFWL_WidgetImpProperties& properties) {
16  IFWL_Barcode* pBarcode = new IFWL_Barcode;
17  CFWL_BarcodeImp* pBarcodeImpl = new CFWL_BarcodeImp(properties, nullptr);
18  pBarcode->SetImpl(pBarcodeImpl);
19  pBarcodeImpl->SetInterface(pBarcode);
20  return pBarcode;
21}
22IFWL_Barcode::IFWL_Barcode() {}
23void IFWL_Barcode::SetType(BC_TYPE type) {
24  static_cast<CFWL_BarcodeImp*>(GetImpl())->SetType(type);
25}
26FX_BOOL IFWL_Barcode::IsProtectedType() {
27  return static_cast<CFWL_BarcodeImp*>(GetImpl())->IsProtectedType();
28}
29
30CFWL_BarcodeImp::CFWL_BarcodeImp(const CFWL_WidgetImpProperties& properties,
31                                 IFWL_Widget* pOuter)
32    : CFWL_EditImp(properties, pOuter),
33      m_pBarcodeEngine(NULL),
34      m_dwStatus(0),
35      m_type(BC_UNKNOWN) {}
36CFWL_BarcodeImp::~CFWL_BarcodeImp() {
37  ReleaseBarcodeEngine();
38}
39FWL_ERR CFWL_BarcodeImp::GetClassName(CFX_WideString& wsClass) const {
40  wsClass = FWL_CLASS_Barcode;
41  return FWL_ERR_Succeeded;
42}
43FX_DWORD CFWL_BarcodeImp::GetClassID() const {
44  return FWL_CLASSHASH_Barcode;
45}
46FWL_ERR CFWL_BarcodeImp::Initialize() {
47  if (!m_pDelegate) {
48    m_pDelegate = new CFWL_BarcodeImpDelegate(this);
49  }
50  if (CFWL_EditImp::Initialize() != FWL_ERR_Succeeded)
51    return FWL_ERR_Indefinite;
52  return FWL_ERR_Succeeded;
53}
54FWL_ERR CFWL_BarcodeImp::Finalize() {
55  delete m_pDelegate;
56  m_pDelegate = nullptr;
57  ReleaseBarcodeEngine();
58  return CFWL_EditImp::Finalize();
59}
60FWL_ERR CFWL_BarcodeImp::Update() {
61  if (IsLocked()) {
62    return FWL_ERR_Indefinite;
63  }
64  FWL_ERR ret = CFWL_EditImp::Update();
65  GenerateBarcodeImageCache();
66  return ret;
67}
68FWL_ERR CFWL_BarcodeImp::DrawWidget(CFX_Graphics* pGraphics,
69                                    const CFX_Matrix* pMatrix) {
70  if (!pGraphics)
71    return FWL_ERR_Indefinite;
72  if (!m_pProperties->m_pThemeProvider)
73    return FWL_ERR_Indefinite;
74  if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
75    GenerateBarcodeImageCache();
76    if (!m_pBarcodeEngine || (m_dwStatus & XFA_BCS_EncodeSuccess) == 0) {
77      return FWL_ERR_Succeeded;
78    }
79    CFX_Matrix mt;
80    mt.e = m_rtClient.left;
81    mt.f = m_rtClient.top;
82    if (pMatrix) {
83      mt.Concat(*pMatrix);
84    }
85    int32_t errorCode = 0;
86    if (!m_pBarcodeEngine->RenderDevice(pGraphics->GetRenderDevice(), pMatrix,
87                                        errorCode)) {
88      return FWL_ERR_Indefinite;
89    }
90    return FWL_ERR_Succeeded;
91  }
92  return CFWL_EditImp::DrawWidget(pGraphics, pMatrix);
93}
94void CFWL_BarcodeImp::GenerateBarcodeImageCache() {
95  if ((m_dwStatus & XFA_BCS_NeedUpdate) == 0)
96    return;
97  m_dwStatus = 0;
98  CreateBarcodeEngine();
99  IFWL_BarcodeDP* pData =
100      static_cast<IFWL_BarcodeDP*>(m_pProperties->m_pDataProvider);
101  if (!pData)
102    return;
103  if (!m_pBarcodeEngine)
104    return;
105  CFX_WideString wsText;
106  if (GetText(wsText) != FWL_ERR_Succeeded)
107    return;
108  CFWL_ThemePart part;
109  part.m_pWidget = m_pInterface;
110  IFWL_ThemeProvider* pTheme = GetAvailableTheme();
111  IFX_Font* pFont =
112      static_cast<IFX_Font*>(pTheme->GetCapacity(&part, FWL_WGTCAPACITY_Font));
113  CFX_Font* pCXFont =
114      pFont ? static_cast<CFX_Font*>(pFont->GetDevFont()) : nullptr;
115  if (pCXFont) {
116    m_pBarcodeEngine->SetFont(pCXFont);
117  }
118  FX_FLOAT* pFontSize = static_cast<FX_FLOAT*>(
119      pTheme->GetCapacity(&part, FWL_WGTCAPACITY_FontSize));
120  if (pFontSize) {
121    m_pBarcodeEngine->SetFontSize(*pFontSize);
122  }
123  FX_ARGB* pFontColor = static_cast<FX_ARGB*>(
124      pTheme->GetCapacity(&part, FWL_WGTCAPACITY_TextColor));
125  if (pFontColor) {
126    m_pBarcodeEngine->SetFontColor(*pFontColor);
127  }
128  m_pBarcodeEngine->SetHeight(int32_t(m_rtClient.height));
129  m_pBarcodeEngine->SetWidth(int32_t(m_rtClient.width));
130  FX_DWORD dwAttributeMask = pData->GetBarcodeAttributeMask();
131  if (dwAttributeMask & FWL_BCDATTRIBUTE_CHARENCODING) {
132    m_pBarcodeEngine->SetCharEncoding(pData->GetCharEncoding());
133  }
134  if (dwAttributeMask & FWL_BCDATTRIBUTE_MODULEHEIGHT) {
135    m_pBarcodeEngine->SetModuleHeight(pData->GetModuleHeight());
136  }
137  if (dwAttributeMask & FWL_BCDATTRIBUTE_MODULEWIDTH) {
138    m_pBarcodeEngine->SetModuleWidth(pData->GetModuleWidth());
139  }
140  if (dwAttributeMask & FWL_BCDATTRIBUTE_DATALENGTH) {
141    m_pBarcodeEngine->SetDataLength(pData->GetDataLength());
142  }
143  if (dwAttributeMask & FWL_BCDATTRIBUTE_CALCHECKSUM) {
144    m_pBarcodeEngine->SetCalChecksum(pData->GetCalChecksum());
145  }
146  if (dwAttributeMask & FWL_BCDATTRIBUTE_PRINTCHECKSUM) {
147    m_pBarcodeEngine->SetPrintChecksum(pData->GetPrintChecksum());
148  }
149  if (dwAttributeMask & FWL_BCDATTRIBUTE_TEXTLOCATION) {
150    m_pBarcodeEngine->SetTextLocation(pData->GetTextLocation());
151  }
152  if (dwAttributeMask & FWL_BCDATTRIBUTE_WIDENARROWRATIO) {
153    m_pBarcodeEngine->SetWideNarrowRatio(pData->GetWideNarrowRatio());
154  }
155  if (dwAttributeMask & FWL_BCDATTRIBUTE_STARTCHAR) {
156    m_pBarcodeEngine->SetStartChar(pData->GetStartChar());
157  }
158  if (dwAttributeMask & FWL_BCDATTRIBUTE_ENDCHAR) {
159    m_pBarcodeEngine->SetEndChar(pData->GetEndChar());
160  }
161  if (dwAttributeMask & FWL_BCDATTRIBUTE_VERSION) {
162    m_pBarcodeEngine->SetVersion(pData->GetVersion());
163  }
164  if (dwAttributeMask & FWL_BCDATTRIBUTE_ECLEVEL) {
165    m_pBarcodeEngine->SetErrorCorrectionLevel(pData->GetErrorCorrectionLevel());
166  }
167  if (dwAttributeMask & FWL_BCDATTRIBUTE_TRUNCATED) {
168    m_pBarcodeEngine->SetTruncated(pData->GetTruncated());
169  }
170  int32_t errorCode = 0;
171  m_dwStatus = m_pBarcodeEngine->Encode(wsText, TRUE, errorCode)
172                   ? XFA_BCS_EncodeSuccess
173                   : 0;
174}
175void CFWL_BarcodeImp::CreateBarcodeEngine() {
176  if ((m_pBarcodeEngine == NULL) && (m_type != BC_UNKNOWN)) {
177    m_pBarcodeEngine = FX_Barcode_Create(m_type);
178  }
179}
180void CFWL_BarcodeImp::ReleaseBarcodeEngine() {
181  if (m_pBarcodeEngine) {
182    m_pBarcodeEngine->Release();
183    m_pBarcodeEngine = NULL;
184  }
185}
186void CFWL_BarcodeImp::SetType(BC_TYPE type) {
187  if (m_type == type) {
188    return;
189  }
190  ReleaseBarcodeEngine();
191  m_type = type;
192  m_dwStatus = XFA_BCS_NeedUpdate;
193}
194FWL_ERR CFWL_BarcodeImp::SetText(const CFX_WideString& wsText) {
195  ReleaseBarcodeEngine();
196  m_dwStatus = XFA_BCS_NeedUpdate;
197  return CFWL_EditImp::SetText(wsText);
198}
199FX_BOOL CFWL_BarcodeImp::IsProtectedType() {
200  if (!m_pBarcodeEngine) {
201    return TRUE;
202  }
203  BC_TYPE tEngineType = m_pBarcodeEngine->GetType();
204  if (tEngineType == BC_QR_CODE || tEngineType == BC_PDF417 ||
205      tEngineType == BC_DATAMATRIX) {
206    return TRUE;
207  }
208  return FALSE;
209}
210CFWL_BarcodeImpDelegate::CFWL_BarcodeImpDelegate(CFWL_BarcodeImp* pOwner)
211    : CFWL_EditImpDelegate(pOwner) {}
212FWL_ERR CFWL_BarcodeImpDelegate::OnProcessEvent(CFWL_Event* pEvent) {
213  FX_DWORD dwFlag = pEvent->GetClassID();
214  if (dwFlag == FWL_EVTHASH_EDT_TextChanged) {
215    CFWL_BarcodeImp* pOwner = static_cast<CFWL_BarcodeImp*>(m_pOwner);
216    pOwner->ReleaseBarcodeEngine();
217    pOwner->m_dwStatus = XFA_BCS_NeedUpdate;
218  }
219  return CFWL_EditImpDelegate::OnProcessEvent(pEvent);
220}
221