Home | History | Annotate | Download | only in parser
      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/fxfa/src/common/xfa_utils.h"
      9 #include "xfa/src/fxfa/src/common/xfa_object.h"
     10 #include "xfa/src/fxfa/src/common/xfa_document.h"
     11 #include "xfa/src/fxfa/src/common/xfa_parser.h"
     12 #include "xfa/src/fxfa/src/common/xfa_script.h"
     13 #include "xfa/src/fxfa/src/common/xfa_docdata.h"
     14 #include "xfa/src/fxfa/src/common/xfa_doclayout.h"
     15 #include "xfa/src/fxfa/src/common/xfa_localemgr.h"
     16 #include "xfa/src/fxfa/src/common/xfa_fm2jsapi.h"
     17 CXFA_Node* XFA_CreateUIChild(CXFA_Node* pNode, XFA_ELEMENT& eWidgetType) {
     18   XFA_ELEMENT eType = pNode->GetClassID();
     19   eWidgetType = eType;
     20   if (eType != XFA_ELEMENT_Field && eType != XFA_ELEMENT_Draw) {
     21     return NULL;
     22   }
     23   eWidgetType = XFA_ELEMENT_UNKNOWN;
     24   XFA_ELEMENT eUIType = XFA_ELEMENT_UNKNOWN;
     25   CXFA_Value defValue = pNode->GetProperty(0, XFA_ELEMENT_Value, TRUE);
     26   XFA_ELEMENT eValueType = (XFA_ELEMENT)defValue.GetChildValueClassID();
     27   switch (eValueType) {
     28     case XFA_ELEMENT_Boolean:
     29       eUIType = XFA_ELEMENT_CheckButton;
     30       break;
     31     case XFA_ELEMENT_Integer:
     32     case XFA_ELEMENT_Decimal:
     33     case XFA_ELEMENT_Float:
     34       eUIType = XFA_ELEMENT_NumericEdit;
     35       break;
     36     case XFA_ELEMENT_ExData:
     37     case XFA_ELEMENT_Text:
     38       eUIType = XFA_ELEMENT_TextEdit;
     39       eWidgetType = XFA_ELEMENT_Text;
     40       break;
     41     case XFA_ELEMENT_Date:
     42     case XFA_ELEMENT_Time:
     43     case XFA_ELEMENT_DateTime:
     44       eUIType = XFA_ELEMENT_DateTimeEdit;
     45       break;
     46     case XFA_ELEMENT_Image:
     47       eUIType = XFA_ELEMENT_ImageEdit;
     48       eWidgetType = XFA_ELEMENT_Image;
     49       break;
     50       ;
     51     case XFA_ELEMENT_Arc:
     52     case XFA_ELEMENT_Line:
     53     case XFA_ELEMENT_Rectangle:
     54       eUIType = XFA_ELEMENT_DefaultUi;
     55       eWidgetType = eValueType;
     56       break;
     57     default:
     58       break;
     59   }
     60   CXFA_Node* pUIChild = NULL;
     61   CXFA_Node* pUI = pNode->GetProperty(0, XFA_ELEMENT_Ui, TRUE);
     62   CXFA_Node* pChild = pUI->GetNodeItem(XFA_NODEITEM_FirstChild);
     63   for (; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
     64     XFA_ELEMENT eChild = pChild->GetClassID();
     65     if (eChild == XFA_ELEMENT_Extras || eChild == XFA_ELEMENT_Picture) {
     66       continue;
     67     }
     68     XFA_LPCPROPERTY pProterty =
     69         XFA_GetPropertyOfElement(XFA_ELEMENT_Ui, eChild, XFA_XDPPACKET_Form);
     70     if (pProterty && (pProterty->uFlags & XFA_PROPERTYFLAG_OneOf)) {
     71       pUIChild = pChild;
     72       break;
     73     }
     74   }
     75   if (eType == XFA_ELEMENT_Draw) {
     76     XFA_ELEMENT eDraw = pUIChild ? pUIChild->GetClassID() : XFA_ELEMENT_UNKNOWN;
     77     switch (eDraw) {
     78       case XFA_ELEMENT_TextEdit:
     79         eWidgetType = XFA_ELEMENT_Text;
     80         break;
     81       case XFA_ELEMENT_ImageEdit:
     82         eWidgetType = XFA_ELEMENT_Image;
     83         break;
     84       default:
     85         eWidgetType =
     86             eWidgetType == XFA_ELEMENT_UNKNOWN ? XFA_ELEMENT_Text : eWidgetType;
     87         break;
     88     }
     89   } else {
     90     if (pUIChild && pUIChild->GetClassID() == XFA_ELEMENT_DefaultUi) {
     91       eWidgetType = XFA_ELEMENT_TextEdit;
     92     } else {
     93       eWidgetType = pUIChild
     94                         ? pUIChild->GetClassID()
     95                         : (eUIType == XFA_ELEMENT_UNKNOWN ? XFA_ELEMENT_TextEdit
     96                                                           : eUIType);
     97     }
     98   }
     99   if (!pUIChild) {
    100     if (eUIType == XFA_ELEMENT_UNKNOWN) {
    101       eUIType = XFA_ELEMENT_TextEdit;
    102       ((CXFA_Node*)defValue)->GetProperty(0, XFA_ELEMENT_Text, TRUE);
    103     }
    104     pUIChild = pUI->GetProperty(0, eUIType, TRUE);
    105   } else if (eUIType == XFA_ELEMENT_UNKNOWN) {
    106     switch (pUIChild->GetClassID()) {
    107       case XFA_ELEMENT_CheckButton: {
    108         eValueType = XFA_ELEMENT_Text;
    109         if (CXFA_Node* pItems = pNode->GetChild(0, XFA_ELEMENT_Items)) {
    110           if (CXFA_Node* pItem = pItems->GetChild(0, XFA_ELEMENT_UNKNOWN)) {
    111             eValueType = pItem->GetClassID();
    112           }
    113         }
    114       } break;
    115       case XFA_ELEMENT_DateTimeEdit:
    116         eValueType = XFA_ELEMENT_DateTime;
    117         break;
    118       case XFA_ELEMENT_ImageEdit:
    119         eValueType = XFA_ELEMENT_Image;
    120         break;
    121       case XFA_ELEMENT_NumericEdit:
    122         eValueType = XFA_ELEMENT_Float;
    123         break;
    124       case XFA_ELEMENT_ChoiceList: {
    125         eValueType = (pUIChild->GetEnum(XFA_ATTRIBUTE_Open) ==
    126                       XFA_ATTRIBUTEENUM_MultiSelect)
    127                          ? XFA_ELEMENT_ExData
    128                          : XFA_ELEMENT_Text;
    129       } break;
    130       case XFA_ELEMENT_Barcode:
    131       case XFA_ELEMENT_Button:
    132       case XFA_ELEMENT_PasswordEdit:
    133       case XFA_ELEMENT_Signature:
    134       case XFA_ELEMENT_TextEdit:
    135       default:
    136         eValueType = XFA_ELEMENT_Text;
    137         break;
    138     }
    139     ((CXFA_Node*)defValue)->GetProperty(0, eValueType, TRUE);
    140   }
    141   return pUIChild;
    142 }
    143 CXFA_LocaleValue XFA_GetLocaleValue(CXFA_WidgetData* pWidgetData) {
    144   CXFA_Node* pNodeValue =
    145       pWidgetData->GetNode()->GetChild(0, XFA_ELEMENT_Value);
    146   if (!pNodeValue) {
    147     return CXFA_LocaleValue();
    148   }
    149   CXFA_Node* pValueChild = pNodeValue->GetNodeItem(XFA_NODEITEM_FirstChild);
    150   if (!pValueChild) {
    151     return CXFA_LocaleValue();
    152   }
    153   int32_t iVTType = XFA_VT_NULL;
    154   XFA_ELEMENT eType = pValueChild->GetClassID();
    155   switch (eType) {
    156     case XFA_ELEMENT_Decimal:
    157       iVTType = XFA_VT_DECIMAL;
    158       break;
    159     case XFA_ELEMENT_Float:
    160       iVTType = XFA_VT_FLOAT;
    161       break;
    162     case XFA_ELEMENT_Date:
    163       iVTType = XFA_VT_DATE;
    164       break;
    165     case XFA_ELEMENT_Time:
    166       iVTType = XFA_VT_TIME;
    167       break;
    168     case XFA_ELEMENT_DateTime:
    169       iVTType = XFA_VT_DATETIME;
    170       break;
    171     case XFA_ELEMENT_Boolean:
    172       iVTType = XFA_VT_BOOLEAN;
    173       break;
    174     case XFA_ELEMENT_Integer:
    175       iVTType = XFA_VT_INTEGER;
    176       break;
    177     case XFA_ELEMENT_Text:
    178       iVTType = XFA_VT_TEXT;
    179       break;
    180     default:
    181       iVTType = XFA_VT_NULL;
    182       break;
    183   }
    184   return CXFA_LocaleValue(iVTType, pWidgetData->GetRawValue(),
    185                           pWidgetData->GetNode()->GetDocument()->GetLocalMgr());
    186 }
    187 void XFA_GetPlainTextFromRichText(IFDE_XMLNode* pXMLNode,
    188                                   CFX_WideString& wsPlainText) {
    189   if (pXMLNode == NULL) {
    190     return;
    191   }
    192   switch (pXMLNode->GetType()) {
    193     case FDE_XMLNODE_Element: {
    194       IFDE_XMLElement* pXMLElement = (IFDE_XMLElement*)pXMLNode;
    195       CFX_WideString wsTag;
    196       pXMLElement->GetLocalTagName(wsTag);
    197       uint32_t uTag = FX_HashCode_String_GetW(wsTag, wsTag.GetLength(), TRUE);
    198       if (uTag == 0x0001f714) {
    199         wsPlainText += L"\n";
    200       } else if (uTag == 0x00000070) {
    201         if (!wsPlainText.IsEmpty()) {
    202           wsPlainText += L"\n";
    203         }
    204       } else if (uTag == 0xa48ac63) {
    205         if (!wsPlainText.IsEmpty() &&
    206             wsPlainText[wsPlainText.GetLength() - 1] != '\n') {
    207           wsPlainText += L"\n";
    208         }
    209       }
    210     } break;
    211     case FDE_XMLNODE_Text: {
    212       CFX_WideString wsContent;
    213       ((IFDE_XMLText*)pXMLNode)->GetText(wsContent);
    214       wsPlainText += wsContent;
    215     } break;
    216     case FDE_XMLNODE_CharData: {
    217       CFX_WideString wsCharData;
    218       ((IFDE_XMLCharData*)pXMLNode)->GetCharData(wsCharData);
    219       wsPlainText += wsCharData;
    220     } break;
    221     default:
    222       break;
    223   }
    224   for (IFDE_XMLNode* pChildXML =
    225            pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild);
    226        pChildXML;
    227        pChildXML = pChildXML->GetNodeItem(IFDE_XMLNode::NextSibling)) {
    228     XFA_GetPlainTextFromRichText(pChildXML, wsPlainText);
    229   }
    230 }
    231 FX_BOOL XFA_FieldIsMultiListBox(CXFA_Node* pFieldNode) {
    232   FX_BOOL bRet = FALSE;
    233   if (!pFieldNode) {
    234     return bRet;
    235   }
    236   CXFA_Node* pUIChild = pFieldNode->GetChild(0, XFA_ELEMENT_Ui);
    237   if (pUIChild) {
    238     CXFA_Node* pFirstChild = pUIChild->GetNodeItem(XFA_NODEITEM_FirstChild);
    239     if (pFirstChild && pFirstChild->GetClassID() == XFA_ELEMENT_ChoiceList) {
    240       bRet = pFirstChild->GetEnum(XFA_ATTRIBUTE_Open) ==
    241              XFA_ATTRIBUTEENUM_MultiSelect;
    242     }
    243   }
    244   return bRet;
    245 }
    246 FX_BOOL XFA_IsLayoutElement(XFA_ELEMENT eElement, FX_BOOL bLayoutContainer) {
    247   switch (eElement) {
    248     case XFA_ELEMENT_Draw:
    249     case XFA_ELEMENT_Field:
    250     case XFA_ELEMENT_InstanceManager:
    251       return !bLayoutContainer;
    252     case XFA_ELEMENT_Area:
    253     case XFA_ELEMENT_Subform:
    254     case XFA_ELEMENT_ExclGroup:
    255     case XFA_ELEMENT_SubformSet:
    256       return TRUE;
    257     case XFA_ELEMENT_PageArea:
    258     case XFA_ELEMENT_Form:
    259       return TRUE;
    260     default:
    261       return FALSE;
    262   }
    263   return FALSE;
    264 }
    265 FX_BOOL XFA_IsTakingupSpace(XFA_ATTRIBUTEENUM ePresence) {
    266   switch (ePresence) {
    267     case XFA_ATTRIBUTEENUM_Visible:
    268     case XFA_ATTRIBUTEENUM_Invisible:
    269       return TRUE;
    270     default:
    271       return FALSE;
    272   }
    273   return FALSE;
    274 }
    275 FX_BOOL XFA_IsFlowingLayout(XFA_ATTRIBUTEENUM eLayout) {
    276   switch (eLayout) {
    277     case XFA_ATTRIBUTEENUM_Tb:
    278     case XFA_ATTRIBUTEENUM_Lr_tb:
    279     case XFA_ATTRIBUTEENUM_Rl_tb:
    280       return TRUE;
    281     default:
    282       return FALSE;
    283   }
    284   return FALSE;
    285 }
    286 FX_BOOL XFA_IsHorizontalFlow(XFA_ATTRIBUTEENUM eLayout) {
    287   switch (eLayout) {
    288     case XFA_ATTRIBUTEENUM_Lr_tb:
    289     case XFA_ATTRIBUTEENUM_Rl_tb:
    290       return TRUE;
    291     default:
    292       return FALSE;
    293   }
    294   return FALSE;
    295 }
    296 static const FX_DOUBLE fraction_scales[] = {0.1,
    297                                             0.01,
    298                                             0.001,
    299                                             0.0001,
    300                                             0.00001,
    301                                             0.000001,
    302                                             0.0000001,
    303                                             0.00000001,
    304                                             0.000000001,
    305                                             0.0000000001,
    306                                             0.00000000001,
    307                                             0.000000000001,
    308                                             0.0000000000001,
    309                                             0.00000000000001,
    310                                             0.000000000000001,
    311                                             0.0000000000000001};
    312 FX_DOUBLE XFA_WideStringToDouble(const CFX_WideString& wsStringVal) {
    313   CFX_WideString wsValue = wsStringVal;
    314   wsValue.TrimLeft();
    315   wsValue.TrimRight();
    316   int64_t nIntegral = 0;
    317   FX_DWORD dwFractional = 0;
    318   int32_t nExponent = 0;
    319   int32_t cc = 0;
    320   FX_BOOL bNegative = FALSE, bExpSign = FALSE;
    321   const FX_WCHAR* str = (const FX_WCHAR*)wsValue;
    322   int32_t len = wsValue.GetLength();
    323   if (str[0] == '+') {
    324     cc++;
    325   } else if (str[0] == '-') {
    326     bNegative = TRUE;
    327     cc++;
    328   }
    329   int32_t nIntegralLen = 0;
    330   while (cc < len) {
    331     if (str[cc] == '.' || str[cc] == 'E' || str[cc] == 'e' ||
    332         nIntegralLen > 17) {
    333       break;
    334     }
    335     if (!XFA_IsDigit(str[cc])) {
    336       return 0;
    337     }
    338     nIntegral = nIntegral * 10 + str[cc] - '0';
    339     cc++;
    340     nIntegralLen++;
    341   }
    342   nIntegral = bNegative ? -nIntegral : nIntegral;
    343   int32_t scale = 0;
    344   FX_DOUBLE fraction = 0.0;
    345   if (cc < len && str[cc] == '.') {
    346     cc++;
    347     while (cc < len) {
    348       fraction += fraction_scales[scale] * (str[cc] - '0');
    349       scale++;
    350       cc++;
    351       if (cc == len) {
    352         break;
    353       }
    354       if (scale == sizeof(fraction_scales) / sizeof(FX_DOUBLE) ||
    355           str[cc] == 'E' || str[cc] == 'e') {
    356         break;
    357       }
    358       if (!XFA_IsDigit(str[cc])) {
    359         return 0;
    360       }
    361     }
    362     dwFractional = (FX_DWORD)(fraction * 4294967296.0);
    363   }
    364   if (cc < len && (str[cc] == 'E' || str[cc] == 'e')) {
    365     cc++;
    366     if (cc < len) {
    367       if (str[cc] == '+') {
    368         cc++;
    369       } else if (str[cc] == '-') {
    370         bExpSign = TRUE;
    371         cc++;
    372       }
    373     }
    374     while (cc < len) {
    375       if (str[cc] == '.' || !XFA_IsDigit(str[cc])) {
    376         return 0;
    377       }
    378       nExponent = nExponent * 10 + str[cc] - '0';
    379       cc++;
    380     }
    381     nExponent = bExpSign ? -nExponent : nExponent;
    382   }
    383   FX_DOUBLE dValue = (dwFractional / 4294967296.0);
    384   dValue = nIntegral + (nIntegral >= 0 ? dValue : -dValue);
    385   if (nExponent != 0) {
    386     dValue *= FXSYS_pow(10, (FX_FLOAT)nExponent);
    387   }
    388   return dValue;
    389 }
    390 
    391 FX_DOUBLE XFA_ByteStringToDouble(const CFX_ByteStringC& szStringVal) {
    392   CFX_WideString wsValue =
    393       CFX_WideString::FromUTF8(szStringVal.GetCStr(), szStringVal.GetLength());
    394   return XFA_WideStringToDouble(wsValue);
    395 }
    396 
    397 int32_t XFA_MapRotation(int32_t nRotation) {
    398   nRotation = nRotation % 360;
    399   nRotation = nRotation < 0 ? nRotation + 360 : nRotation;
    400   return nRotation;
    401 }
    402