1// Copyright 2016 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 "fpdfsdk/cfx_systemhandler.h"
8
9#include <memory>
10
11#include "core/fpdfapi/parser/cpdf_document.h"
12#include "core/fxge/cfx_fontmapper.h"
13#include "core/fxge/cfx_fontmgr.h"
14#include "core/fxge/cfx_gemodule.h"
15#include "fpdfsdk/cpdfsdk_annot.h"
16#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
17#include "fpdfsdk/cpdfsdk_pageview.h"
18#include "fpdfsdk/cpdfsdk_widget.h"
19#include "fpdfsdk/formfiller/cffl_formfiller.h"
20
21namespace {
22
23int CharSet2CP(int charset) {
24  if (charset == FXFONT_SHIFTJIS_CHARSET)
25    return 932;
26  if (charset == FXFONT_GB2312_CHARSET)
27    return 936;
28  if (charset == FXFONT_HANGUL_CHARSET)
29    return 949;
30  if (charset == FXFONT_CHINESEBIG5_CHARSET)
31    return 950;
32  return 0;
33}
34
35}  // namespace
36
37void CFX_SystemHandler::InvalidateRect(CPDFSDK_Widget* widget, FX_RECT rect) {
38  CPDFSDK_PageView* pPageView = widget->GetPageView();
39  UnderlyingPageType* pPage = widget->GetUnderlyingPage();
40  if (!pPage || !pPageView)
41    return;
42
43  CFX_Matrix page2device;
44  pPageView->GetCurrentMatrix(page2device);
45
46  CFX_Matrix device2page;
47  device2page.SetReverse(page2device);
48
49  CFX_PointF left_top = device2page.Transform(CFX_PointF(
50      static_cast<FX_FLOAT>(rect.left), static_cast<FX_FLOAT>(rect.top)));
51  CFX_PointF right_bottom = device2page.Transform(CFX_PointF(
52      static_cast<FX_FLOAT>(rect.right), static_cast<FX_FLOAT>(rect.bottom)));
53
54  CFX_FloatRect rcPDF(left_top.x, right_bottom.y, right_bottom.x, left_top.y);
55  rcPDF.Normalize();
56  m_pFormFillEnv->Invalidate(pPage, rcPDF.ToFxRect());
57}
58
59void CFX_SystemHandler::OutputSelectedRect(CFFL_FormFiller* pFormFiller,
60                                           CFX_FloatRect& rect) {
61  if (!pFormFiller)
62    return;
63
64  CFX_PointF ptA = pFormFiller->PWLtoFFL(CFX_PointF(rect.left, rect.bottom));
65  CFX_PointF ptB = pFormFiller->PWLtoFFL(CFX_PointF(rect.right, rect.top));
66
67  CPDFSDK_Annot* pAnnot = pFormFiller->GetSDKAnnot();
68  UnderlyingPageType* pPage = pAnnot->GetUnderlyingPage();
69  ASSERT(pPage);
70
71  m_pFormFillEnv->OutputSelectedRect(pPage,
72                                     CFX_FloatRect(ptA.x, ptA.y, ptB.x, ptB.y));
73}
74
75bool CFX_SystemHandler::IsSelectionImplemented() const {
76  if (!m_pFormFillEnv)
77    return false;
78
79  FPDF_FORMFILLINFO* pInfo = m_pFormFillEnv->GetFormFillInfo();
80  return pInfo && pInfo->FFI_OutputSelectedRect;
81}
82
83void CFX_SystemHandler::SetCursor(int32_t nCursorType) {
84  m_pFormFillEnv->SetCursor(nCursorType);
85}
86
87bool CFX_SystemHandler::FindNativeTrueTypeFont(CFX_ByteString sFontFaceName) {
88  CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
89  if (!pFontMgr)
90    return false;
91
92  CFX_FontMapper* pFontMapper = pFontMgr->GetBuiltinMapper();
93  if (!pFontMapper)
94    return false;
95
96  if (pFontMapper->m_InstalledTTFonts.empty())
97    pFontMapper->LoadInstalledFonts();
98
99  for (const auto& font : pFontMapper->m_InstalledTTFonts) {
100    if (font.Compare(sFontFaceName.AsStringC()))
101      return true;
102  }
103  for (const auto& fontPair : pFontMapper->m_LocalizedTTFonts) {
104    if (fontPair.first.Compare(sFontFaceName.AsStringC()))
105      return true;
106  }
107  return false;
108}
109
110CPDF_Font* CFX_SystemHandler::AddNativeTrueTypeFontToPDF(
111    CPDF_Document* pDoc,
112    CFX_ByteString sFontFaceName,
113    uint8_t nCharset) {
114  if (!pDoc)
115    return nullptr;
116
117  std::unique_ptr<CFX_Font> pFXFont(new CFX_Font);
118  pFXFont->LoadSubst(sFontFaceName, true, 0, 0, 0, CharSet2CP(nCharset), false);
119  return pDoc->AddFont(pFXFont.get(), nCharset, false);
120}
121
122int32_t CFX_SystemHandler::SetTimer(int32_t uElapse,
123                                    TimerCallback lpTimerFunc) {
124  return m_pFormFillEnv->SetTimer(uElapse, lpTimerFunc);
125}
126
127void CFX_SystemHandler::KillTimer(int32_t nID) {
128  m_pFormFillEnv->KillTimer(nID);
129}
130
131bool CFX_SystemHandler::IsSHIFTKeyDown(uint32_t nFlag) const {
132  return !!m_pFormFillEnv->IsSHIFTKeyDown(nFlag);
133}
134
135bool CFX_SystemHandler::IsCTRLKeyDown(uint32_t nFlag) const {
136  return !!m_pFormFillEnv->IsCTRLKeyDown(nFlag);
137}
138
139bool CFX_SystemHandler::IsALTKeyDown(uint32_t nFlag) const {
140  return !!m_pFormFillEnv->IsALTKeyDown(nFlag);
141}
142