Home | History | Annotate | Download | only in fxfa
      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/fxfa/cxfa_ffwidgethandler.h"
      8 
      9 #include <vector>
     10 
     11 #include "fxjs/xfa/cjx_object.h"
     12 #include "xfa/fxfa/cxfa_ffdoc.h"
     13 #include "xfa/fxfa/cxfa_ffdocview.h"
     14 #include "xfa/fxfa/cxfa_fffield.h"
     15 #include "xfa/fxfa/cxfa_ffwidget.h"
     16 #include "xfa/fxfa/cxfa_fwladapterwidgetmgr.h"
     17 #include "xfa/fxfa/parser/cxfa_calculate.h"
     18 #include "xfa/fxfa/parser/cxfa_checkbutton.h"
     19 #include "xfa/fxfa/parser/cxfa_layoutprocessor.h"
     20 #include "xfa/fxfa/parser/cxfa_measurement.h"
     21 #include "xfa/fxfa/parser/cxfa_node.h"
     22 #include "xfa/fxfa/parser/cxfa_ui.h"
     23 #include "xfa/fxfa/parser/cxfa_validate.h"
     24 
     25 CXFA_FFWidgetHandler::CXFA_FFWidgetHandler(CXFA_FFDocView* pDocView)
     26     : m_pDocView(pDocView) {}
     27 
     28 CXFA_FFWidgetHandler::~CXFA_FFWidgetHandler() {}
     29 
     30 bool CXFA_FFWidgetHandler::OnMouseEnter(CXFA_FFWidget* hWidget) {
     31   m_pDocView->LockUpdate();
     32   bool bRet = hWidget->OnMouseEnter();
     33   m_pDocView->UnlockUpdate();
     34   m_pDocView->UpdateDocView();
     35   return bRet;
     36 }
     37 
     38 bool CXFA_FFWidgetHandler::OnMouseExit(CXFA_FFWidget* hWidget) {
     39   m_pDocView->LockUpdate();
     40   bool bRet = hWidget->OnMouseExit();
     41   m_pDocView->UnlockUpdate();
     42   m_pDocView->UpdateDocView();
     43   return bRet;
     44 }
     45 
     46 bool CXFA_FFWidgetHandler::OnLButtonDown(CXFA_FFWidget* hWidget,
     47                                          uint32_t dwFlags,
     48                                          const CFX_PointF& point) {
     49   m_pDocView->LockUpdate();
     50   bool bRet = hWidget->OnLButtonDown(dwFlags, hWidget->Rotate2Normal(point));
     51   if (bRet && m_pDocView->SetFocus(hWidget)) {
     52     m_pDocView->GetDoc()->GetDocEnvironment()->SetFocusWidget(
     53         m_pDocView->GetDoc(), hWidget);
     54   }
     55   m_pDocView->UnlockUpdate();
     56   m_pDocView->UpdateDocView();
     57   return bRet;
     58 }
     59 
     60 bool CXFA_FFWidgetHandler::OnLButtonUp(CXFA_FFWidget* hWidget,
     61                                        uint32_t dwFlags,
     62                                        const CFX_PointF& point) {
     63   m_pDocView->LockUpdate();
     64   m_pDocView->m_bLayoutEvent = true;
     65   bool bRet = hWidget->OnLButtonUp(dwFlags, hWidget->Rotate2Normal(point));
     66   m_pDocView->UnlockUpdate();
     67   m_pDocView->UpdateDocView();
     68   return bRet;
     69 }
     70 
     71 bool CXFA_FFWidgetHandler::OnLButtonDblClk(CXFA_FFWidget* hWidget,
     72                                            uint32_t dwFlags,
     73                                            const CFX_PointF& point) {
     74   bool bRet = hWidget->OnLButtonDblClk(dwFlags, hWidget->Rotate2Normal(point));
     75   m_pDocView->RunInvalidate();
     76   return bRet;
     77 }
     78 
     79 bool CXFA_FFWidgetHandler::OnMouseMove(CXFA_FFWidget* hWidget,
     80                                        uint32_t dwFlags,
     81                                        const CFX_PointF& point) {
     82   bool bRet = hWidget->OnMouseMove(dwFlags, hWidget->Rotate2Normal(point));
     83   m_pDocView->RunInvalidate();
     84   return bRet;
     85 }
     86 
     87 bool CXFA_FFWidgetHandler::OnMouseWheel(CXFA_FFWidget* hWidget,
     88                                         uint32_t dwFlags,
     89                                         int16_t zDelta,
     90                                         const CFX_PointF& point) {
     91   bool bRet =
     92       hWidget->OnMouseWheel(dwFlags, zDelta, hWidget->Rotate2Normal(point));
     93   m_pDocView->RunInvalidate();
     94   return bRet;
     95 }
     96 
     97 bool CXFA_FFWidgetHandler::OnRButtonDown(CXFA_FFWidget* hWidget,
     98                                          uint32_t dwFlags,
     99                                          const CFX_PointF& point) {
    100   bool bRet = hWidget->OnRButtonDown(dwFlags, hWidget->Rotate2Normal(point));
    101   if (bRet && m_pDocView->SetFocus(hWidget)) {
    102     m_pDocView->GetDoc()->GetDocEnvironment()->SetFocusWidget(
    103         m_pDocView->GetDoc(), hWidget);
    104   }
    105   m_pDocView->RunInvalidate();
    106   return bRet;
    107 }
    108 
    109 bool CXFA_FFWidgetHandler::OnRButtonUp(CXFA_FFWidget* hWidget,
    110                                        uint32_t dwFlags,
    111                                        const CFX_PointF& point) {
    112   bool bRet = hWidget->OnRButtonUp(dwFlags, hWidget->Rotate2Normal(point));
    113   m_pDocView->RunInvalidate();
    114   return bRet;
    115 }
    116 
    117 bool CXFA_FFWidgetHandler::OnRButtonDblClk(CXFA_FFWidget* hWidget,
    118                                            uint32_t dwFlags,
    119                                            const CFX_PointF& point) {
    120   bool bRet = hWidget->OnRButtonDblClk(dwFlags, hWidget->Rotate2Normal(point));
    121   m_pDocView->RunInvalidate();
    122   return bRet;
    123 }
    124 
    125 bool CXFA_FFWidgetHandler::OnKeyDown(CXFA_FFWidget* hWidget,
    126                                      uint32_t dwKeyCode,
    127                                      uint32_t dwFlags) {
    128   bool bRet = hWidget->OnKeyDown(dwKeyCode, dwFlags);
    129   m_pDocView->RunInvalidate();
    130   m_pDocView->UpdateDocView();
    131   return bRet;
    132 }
    133 
    134 bool CXFA_FFWidgetHandler::OnKeyUp(CXFA_FFWidget* hWidget,
    135                                    uint32_t dwKeyCode,
    136                                    uint32_t dwFlags) {
    137   bool bRet = hWidget->OnKeyUp(dwKeyCode, dwFlags);
    138   m_pDocView->RunInvalidate();
    139   return bRet;
    140 }
    141 
    142 bool CXFA_FFWidgetHandler::OnChar(CXFA_FFWidget* hWidget,
    143                                   uint32_t dwChar,
    144                                   uint32_t dwFlags) {
    145   bool bRet = hWidget->OnChar(dwChar, dwFlags);
    146   m_pDocView->RunInvalidate();
    147   return bRet;
    148 }
    149 
    150 WideString CXFA_FFWidgetHandler::GetSelectedText(CXFA_FFWidget* widget) {
    151   if (!widget->CanCopy())
    152     return WideString();
    153 
    154   return widget->Copy().value_or(WideString());
    155 }
    156 
    157 void CXFA_FFWidgetHandler::PasteText(CXFA_FFWidget* widget,
    158                                      const WideString& text) {
    159   if (!widget->CanPaste())
    160     return;
    161 
    162   widget->Paste(text);
    163 }
    164 
    165 FWL_WidgetHit CXFA_FFWidgetHandler::OnHitTest(CXFA_FFWidget* hWidget,
    166                                               const CFX_PointF& point) {
    167   if (!(hWidget->GetStatus() & XFA_WidgetStatus_Visible))
    168     return FWL_WidgetHit::Unknown;
    169   return hWidget->OnHitTest(hWidget->Rotate2Normal(point));
    170 }
    171 
    172 bool CXFA_FFWidgetHandler::OnSetCursor(CXFA_FFWidget* hWidget,
    173                                        const CFX_PointF& point) {
    174   return hWidget->OnSetCursor(hWidget->Rotate2Normal(point));
    175 }
    176 
    177 void CXFA_FFWidgetHandler::RenderWidget(CXFA_FFWidget* hWidget,
    178                                         CXFA_Graphics* pGS,
    179                                         const CFX_Matrix& matrix,
    180                                         bool bHighlight) {
    181   hWidget->RenderWidget(pGS, matrix,
    182                         bHighlight ? XFA_WidgetStatus_Highlight : 0);
    183 }
    184 
    185 bool CXFA_FFWidgetHandler::HasEvent(CXFA_WidgetAcc* pWidgetAcc,
    186                                     XFA_EVENTTYPE eEventType) {
    187   if (eEventType == XFA_EVENT_Unknown)
    188     return false;
    189   if (!pWidgetAcc)
    190     return false;
    191 
    192   CXFA_Node* node = pWidgetAcc->GetNode();
    193   if (!node || node->GetElementType() == XFA_Element::Draw)
    194     return false;
    195 
    196   switch (eEventType) {
    197     case XFA_EVENT_Calculate: {
    198       CXFA_Calculate* calc = node->GetCalculateIfExists();
    199       return calc && calc->GetScriptIfExists();
    200     }
    201     case XFA_EVENT_Validate: {
    202       CXFA_Validate* validate = node->GetValidateIfExists();
    203       return validate && validate->GetScriptIfExists();
    204     }
    205     default:
    206       break;
    207   }
    208   return !pWidgetAcc->GetEventByActivity(gs_EventActivity[eEventType], false)
    209               .empty();
    210 }
    211 
    212 int32_t CXFA_FFWidgetHandler::ProcessEvent(CXFA_WidgetAcc* pWidgetAcc,
    213                                            CXFA_EventParam* pParam) {
    214   if (!pParam || pParam->m_eType == XFA_EVENT_Unknown)
    215     return XFA_EVENTERROR_NotExist;
    216   if (!pWidgetAcc)
    217     return XFA_EVENTERROR_NotExist;
    218 
    219   CXFA_Node* node = pWidgetAcc->GetNode();
    220   if (!node || node->GetElementType() == XFA_Element::Draw)
    221     return XFA_EVENTERROR_NotExist;
    222 
    223   switch (pParam->m_eType) {
    224     case XFA_EVENT_Calculate:
    225       return node->ProcessCalculate(m_pDocView);
    226     case XFA_EVENT_Validate:
    227       if (m_pDocView->GetDoc()->GetDocEnvironment()->IsValidationsEnabled(
    228               m_pDocView->GetDoc())) {
    229         return node->ProcessValidate(m_pDocView, 0);
    230       }
    231       return XFA_EVENTERROR_Disabled;
    232     case XFA_EVENT_InitCalculate: {
    233       CXFA_Calculate* calc = node->GetCalculateIfExists();
    234       if (!calc)
    235         return XFA_EVENTERROR_NotExist;
    236       if (node->IsUserInteractive())
    237         return XFA_EVENTERROR_Disabled;
    238       return node->ExecuteScript(m_pDocView, calc->GetScriptIfExists(), pParam);
    239     }
    240     default:
    241       break;
    242   }
    243   int32_t iRet =
    244       node->ProcessEvent(m_pDocView, gs_EventActivity[pParam->m_eType], pParam);
    245   return iRet;
    246 }
    247 
    248 CXFA_FFWidget* CXFA_FFWidgetHandler::CreateWidget(CXFA_FFWidget* hParent,
    249                                                   XFA_WIDGETTYPE eType,
    250                                                   CXFA_FFWidget* hBefore) {
    251   CXFA_Node* pParentFormItem = hParent ? hParent->GetNode() : nullptr;
    252   CXFA_Node* pBeforeFormItem = hBefore ? hBefore->GetNode() : nullptr;
    253   CXFA_Node* pNewFormItem =
    254       CreateWidgetFormItem(eType, pParentFormItem, pBeforeFormItem);
    255   if (!pNewFormItem)
    256     return nullptr;
    257 
    258   CXFA_Node* templateNode = pNewFormItem->GetTemplateNodeIfExists();
    259   if (!templateNode)
    260     return nullptr;
    261 
    262   templateNode->SetFlag(XFA_NodeFlag_Initialized, true);
    263   pNewFormItem->SetFlag(XFA_NodeFlag_Initialized, true);
    264   m_pDocView->RunLayout();
    265   CXFA_LayoutItem* pLayout =
    266       m_pDocView->GetXFALayout()->GetLayoutItem(pNewFormItem);
    267   return static_cast<CXFA_FFWidget*>(pLayout);
    268 }
    269 
    270 CXFA_Node* CXFA_FFWidgetHandler::CreateWidgetFormItem(
    271     XFA_WIDGETTYPE eType,
    272     CXFA_Node* pParent,
    273     CXFA_Node* pBefore) const {
    274   switch (eType) {
    275     case XFA_WIDGETTYPE_Barcode:
    276       return nullptr;
    277     case XFA_WIDGETTYPE_PushButton:
    278       return CreatePushButton(pParent, pBefore);
    279     case XFA_WIDGETTYPE_CheckButton:
    280       return CreateCheckButton(pParent, pBefore);
    281     case XFA_WIDGETTYPE_ExcludeGroup:
    282       return CreateExclGroup(pParent, pBefore);
    283     case XFA_WIDGETTYPE_RadioButton:
    284       return CreateRadioButton(pParent, pBefore);
    285     case XFA_WIDGETTYPE_Arc:
    286       return CreateArc(pParent, pBefore);
    287     case XFA_WIDGETTYPE_Rectangle:
    288       return CreateRectangle(pParent, pBefore);
    289     case XFA_WIDGETTYPE_Image:
    290       return CreateImage(pParent, pBefore);
    291     case XFA_WIDGETTYPE_Line:
    292       return CreateLine(pParent, pBefore);
    293     case XFA_WIDGETTYPE_Text:
    294       return CreateText(pParent, pBefore);
    295     case XFA_WIDGETTYPE_DatetimeEdit:
    296       return CreateDatetimeEdit(pParent, pBefore);
    297     case XFA_WIDGETTYPE_DecimalField:
    298       return CreateDecimalField(pParent, pBefore);
    299     case XFA_WIDGETTYPE_NumericField:
    300       return CreateNumericField(pParent, pBefore);
    301     case XFA_WIDGETTYPE_Signature:
    302       return CreateSignature(pParent, pBefore);
    303     case XFA_WIDGETTYPE_TextEdit:
    304       return CreateTextEdit(pParent, pBefore);
    305     case XFA_WIDGETTYPE_DropdownList:
    306       return CreateDropdownList(pParent, pBefore);
    307     case XFA_WIDGETTYPE_ListBox:
    308       return CreateListBox(pParent, pBefore);
    309     case XFA_WIDGETTYPE_ImageField:
    310       return CreateImageField(pParent, pBefore);
    311     case XFA_WIDGETTYPE_PasswordEdit:
    312       return CreatePasswordEdit(pParent, pBefore);
    313     case XFA_WIDGETTYPE_Subform:
    314       return CreateSubform(pParent, pBefore);
    315     default:
    316       return nullptr;
    317   }
    318 }
    319 
    320 CXFA_Node* CXFA_FFWidgetHandler::CreatePushButton(CXFA_Node* pParent,
    321                                                   CXFA_Node* pBefore) const {
    322   CXFA_Node* pField = CreateField(XFA_Element::Button, pParent, pBefore);
    323   CXFA_Node* pCaption = CreateCopyNode(XFA_Element::Caption, pField);
    324   CXFA_Node* pValue = CreateCopyNode(XFA_Element::Value, pCaption);
    325   CXFA_Node* pText = CreateCopyNode(XFA_Element::Text, pValue);
    326   pText->JSObject()->SetContent(L"Button", L"Button", false, false, true);
    327 
    328   CXFA_Node* pPara = CreateCopyNode(XFA_Element::Para, pCaption);
    329   pPara->JSObject()->SetEnum(XFA_Attribute::VAlign, XFA_AttributeEnum::Middle,
    330                              false);
    331   pPara->JSObject()->SetEnum(XFA_Attribute::HAlign, XFA_AttributeEnum::Center,
    332                              false);
    333   CreateFontNode(pCaption);
    334 
    335   CXFA_Node* pBorder = CreateCopyNode(XFA_Element::Border, pField);
    336   pBorder->JSObject()->SetEnum(XFA_Attribute::Hand, XFA_AttributeEnum::Right,
    337                                false);
    338 
    339   CXFA_Node* pEdge = CreateCopyNode(XFA_Element::Edge, pBorder);
    340   pEdge->JSObject()->SetEnum(XFA_Attribute::Stroke, XFA_AttributeEnum::Raised,
    341                              false);
    342 
    343   CXFA_Node* pFill = CreateCopyNode(XFA_Element::Fill, pBorder);
    344   CXFA_Node* pColor = CreateCopyNode(XFA_Element::Color, pFill);
    345   pColor->JSObject()->SetCData(XFA_Attribute::Value, L"212, 208, 200", false,
    346                                false);
    347 
    348   CXFA_Node* pBind = CreateCopyNode(XFA_Element::Bind, pField);
    349   pBind->JSObject()->SetEnum(XFA_Attribute::Match, XFA_AttributeEnum::None,
    350                              false);
    351 
    352   return pField;
    353 }
    354 
    355 CXFA_Node* CXFA_FFWidgetHandler::CreateCheckButton(CXFA_Node* pParent,
    356                                                    CXFA_Node* pBefore) const {
    357   return CreateField(XFA_Element::CheckButton, pParent, pBefore);
    358 }
    359 
    360 CXFA_Node* CXFA_FFWidgetHandler::CreateExclGroup(CXFA_Node* pParent,
    361                                                  CXFA_Node* pBefore) const {
    362   return CreateFormItem(XFA_Element::ExclGroup, pParent, pBefore);
    363 }
    364 
    365 CXFA_Node* CXFA_FFWidgetHandler::CreateRadioButton(CXFA_Node* pParent,
    366                                                    CXFA_Node* pBefore) const {
    367   CXFA_Node* pField = CreateField(XFA_Element::CheckButton, pParent, pBefore);
    368   CXFA_Ui* pUi = pField->GetFirstChildByClass<CXFA_Ui>(XFA_Element::Ui);
    369   CXFA_CheckButton* pWidget =
    370       pUi->GetFirstChildByClass<CXFA_CheckButton>(XFA_Element::CheckButton);
    371   pWidget->JSObject()->SetEnum(XFA_Attribute::Shape, XFA_AttributeEnum::Round,
    372                                false);
    373   return pField;
    374 }
    375 
    376 CXFA_Node* CXFA_FFWidgetHandler::CreateDatetimeEdit(CXFA_Node* pParent,
    377                                                     CXFA_Node* pBefore) const {
    378   CXFA_Node* pField = CreateField(XFA_Element::DateTimeEdit, pParent, pBefore);
    379   CreateValueNode(XFA_Element::Date, pField);
    380   return pField;
    381 }
    382 
    383 CXFA_Node* CXFA_FFWidgetHandler::CreateDecimalField(CXFA_Node* pParent,
    384                                                     CXFA_Node* pBefore) const {
    385   CXFA_Node* pField = CreateNumericField(pParent, pBefore);
    386   CreateValueNode(XFA_Element::Decimal, pField);
    387   return pField;
    388 }
    389 
    390 CXFA_Node* CXFA_FFWidgetHandler::CreateNumericField(CXFA_Node* pParent,
    391                                                     CXFA_Node* pBefore) const {
    392   return CreateField(XFA_Element::NumericEdit, pParent, pBefore);
    393 }
    394 
    395 CXFA_Node* CXFA_FFWidgetHandler::CreateSignature(CXFA_Node* pParent,
    396                                                  CXFA_Node* pBefore) const {
    397   return CreateField(XFA_Element::Signature, pParent, pBefore);
    398 }
    399 
    400 CXFA_Node* CXFA_FFWidgetHandler::CreateTextEdit(CXFA_Node* pParent,
    401                                                 CXFA_Node* pBefore) const {
    402   return CreateField(XFA_Element::TextEdit, pParent, pBefore);
    403 }
    404 
    405 CXFA_Node* CXFA_FFWidgetHandler::CreateDropdownList(CXFA_Node* pParent,
    406                                                     CXFA_Node* pBefore) const {
    407   return CreateField(XFA_Element::ChoiceList, pParent, pBefore);
    408 }
    409 
    410 CXFA_Node* CXFA_FFWidgetHandler::CreateListBox(CXFA_Node* pParent,
    411                                                CXFA_Node* pBefore) const {
    412   CXFA_Node* pField = CreateDropdownList(pParent, pBefore);
    413   CXFA_Node* pUi = pField->GetFirstChild();
    414   CXFA_Node* pListBox = pUi->GetFirstChild();
    415   pListBox->JSObject()->SetEnum(XFA_Attribute::Open, XFA_AttributeEnum::Always,
    416                                 false);
    417   pListBox->JSObject()->SetEnum(XFA_Attribute::CommitOn,
    418                                 XFA_AttributeEnum::Exit, false);
    419   return pField;
    420 }
    421 
    422 CXFA_Node* CXFA_FFWidgetHandler::CreateImageField(CXFA_Node* pParent,
    423                                                   CXFA_Node* pBefore) const {
    424   return CreateField(XFA_Element::ImageEdit, pParent, pBefore);
    425 }
    426 
    427 CXFA_Node* CXFA_FFWidgetHandler::CreatePasswordEdit(CXFA_Node* pParent,
    428                                                     CXFA_Node* pBefore) const {
    429   CXFA_Node* pField = CreateField(XFA_Element::PasswordEdit, pParent, pBefore);
    430   CXFA_Node* pBind = CreateCopyNode(XFA_Element::Bind, pField);
    431   pBind->JSObject()->SetEnum(XFA_Attribute::Match, XFA_AttributeEnum::None,
    432                              false);
    433   return pField;
    434 }
    435 
    436 CXFA_Node* CXFA_FFWidgetHandler::CreateField(XFA_Element eElement,
    437                                              CXFA_Node* pParent,
    438                                              CXFA_Node* pBefore) const {
    439   CXFA_Node* pField = CreateFormItem(XFA_Element::Field, pParent, pBefore);
    440   CreateCopyNode(eElement, CreateCopyNode(XFA_Element::Ui, pField));
    441   CreateFontNode(pField);
    442   return pField;
    443 }
    444 
    445 CXFA_Node* CXFA_FFWidgetHandler::CreateArc(CXFA_Node* pParent,
    446                                            CXFA_Node* pBefore) const {
    447   return CreateDraw(XFA_Element::Arc, pParent, pBefore);
    448 }
    449 
    450 CXFA_Node* CXFA_FFWidgetHandler::CreateRectangle(CXFA_Node* pParent,
    451                                                  CXFA_Node* pBefore) const {
    452   return CreateDraw(XFA_Element::Rectangle, pParent, pBefore);
    453 }
    454 
    455 CXFA_Node* CXFA_FFWidgetHandler::CreateImage(CXFA_Node* pParent,
    456                                              CXFA_Node* pBefore) const {
    457   CXFA_Node* pField = CreateDraw(XFA_Element::Image, pParent, pBefore);
    458   CreateCopyNode(XFA_Element::ImageEdit,
    459                  CreateCopyNode(XFA_Element::Ui, pField));
    460   return pField;
    461 }
    462 
    463 CXFA_Node* CXFA_FFWidgetHandler::CreateLine(CXFA_Node* pParent,
    464                                             CXFA_Node* pBefore) const {
    465   return CreateDraw(XFA_Element::Line, pParent, pBefore);
    466 }
    467 
    468 CXFA_Node* CXFA_FFWidgetHandler::CreateText(CXFA_Node* pParent,
    469                                             CXFA_Node* pBefore) const {
    470   CXFA_Node* pField = CreateDraw(XFA_Element::Text, pParent, pBefore);
    471   CreateCopyNode(XFA_Element::TextEdit,
    472                  CreateCopyNode(XFA_Element::Ui, pField));
    473   CreateFontNode(pField);
    474   return pField;
    475 }
    476 
    477 CXFA_Node* CXFA_FFWidgetHandler::CreateDraw(XFA_Element eElement,
    478                                             CXFA_Node* pParent,
    479                                             CXFA_Node* pBefore) const {
    480   CXFA_Node* pDraw = CreateFormItem(XFA_Element::Draw, pParent, pBefore);
    481   CreateValueNode(eElement, pDraw);
    482   return pDraw;
    483 }
    484 
    485 CXFA_Node* CXFA_FFWidgetHandler::CreateSubform(CXFA_Node* pParent,
    486                                                CXFA_Node* pBefore) const {
    487   return CreateFormItem(XFA_Element::Subform, pParent, pBefore);
    488 }
    489 
    490 CXFA_Node* CXFA_FFWidgetHandler::CreateFormItem(XFA_Element eElement,
    491                                                 CXFA_Node* pParent,
    492                                                 CXFA_Node* pBefore) const {
    493   if (!pParent)
    494     return nullptr;
    495 
    496   CXFA_Node* pTemplateParent = pParent->GetTemplateNodeIfExists();
    497   if (!pTemplateParent)
    498     return nullptr;
    499 
    500   CXFA_Node* pNewFormItem = pTemplateParent->CloneTemplateToForm(false);
    501   if (pParent)
    502     pParent->InsertChild(pNewFormItem, pBefore);
    503   return pNewFormItem;
    504 }
    505 
    506 CXFA_Node* CXFA_FFWidgetHandler::CreateCopyNode(XFA_Element eElement,
    507                                                 CXFA_Node* pParent,
    508                                                 CXFA_Node* pBefore) const {
    509   if (!pParent)
    510     return nullptr;
    511 
    512   CXFA_Node* pTemplateParent = pParent->GetTemplateNodeIfExists();
    513   CXFA_Node* pNewNode =
    514       CreateTemplateNode(eElement, pTemplateParent,
    515                          pBefore ? pBefore->GetTemplateNodeIfExists() : nullptr)
    516           ->Clone(false);
    517   if (pParent)
    518     pParent->InsertChild(pNewNode, pBefore);
    519   return pNewNode;
    520 }
    521 
    522 CXFA_Node* CXFA_FFWidgetHandler::CreateTemplateNode(XFA_Element eElement,
    523                                                     CXFA_Node* pParent,
    524                                                     CXFA_Node* pBefore) const {
    525   CXFA_Document* pXFADoc = GetXFADoc();
    526   CXFA_Node* pNewTemplateNode =
    527       pXFADoc->CreateNode(XFA_PacketType::Template, eElement);
    528   if (pParent)
    529     pParent->InsertChild(pNewTemplateNode, pBefore);
    530   return pNewTemplateNode;
    531 }
    532 
    533 CXFA_Node* CXFA_FFWidgetHandler::CreateFontNode(CXFA_Node* pParent) const {
    534   CXFA_Node* pFont = CreateCopyNode(XFA_Element::Font, pParent);
    535   pFont->JSObject()->SetCData(XFA_Attribute::Typeface, L"Myriad Pro", false,
    536                               false);
    537   return pFont;
    538 }
    539 
    540 CXFA_Node* CXFA_FFWidgetHandler::CreateMarginNode(CXFA_Node* pParent,
    541                                                   uint32_t dwFlags,
    542                                                   float fInsets[4]) const {
    543   CXFA_Node* pMargin = CreateCopyNode(XFA_Element::Margin, pParent);
    544   if (dwFlags & 0x01)
    545     pMargin->JSObject()->SetMeasure(XFA_Attribute::LeftInset,
    546                                     CXFA_Measurement(fInsets[0], XFA_Unit::Pt),
    547                                     false);
    548   if (dwFlags & 0x02)
    549     pMargin->JSObject()->SetMeasure(XFA_Attribute::TopInset,
    550                                     CXFA_Measurement(fInsets[1], XFA_Unit::Pt),
    551                                     false);
    552   if (dwFlags & 0x04)
    553     pMargin->JSObject()->SetMeasure(XFA_Attribute::RightInset,
    554                                     CXFA_Measurement(fInsets[2], XFA_Unit::Pt),
    555                                     false);
    556   if (dwFlags & 0x08)
    557     pMargin->JSObject()->SetMeasure(XFA_Attribute::BottomInset,
    558                                     CXFA_Measurement(fInsets[3], XFA_Unit::Pt),
    559                                     false);
    560   return pMargin;
    561 }
    562 
    563 CXFA_Node* CXFA_FFWidgetHandler::CreateValueNode(XFA_Element eValue,
    564                                                  CXFA_Node* pParent) const {
    565   CXFA_Node* pValue = CreateCopyNode(XFA_Element::Value, pParent);
    566   CreateCopyNode(eValue, pValue);
    567   return pValue;
    568 }
    569 
    570 CXFA_Document* CXFA_FFWidgetHandler::GetObjFactory() const {
    571   return GetXFADoc();
    572 }
    573 
    574 CXFA_Document* CXFA_FFWidgetHandler::GetXFADoc() const {
    575   return m_pDocView->GetDoc()->GetXFADoc();
    576 }
    577