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 #include "xfa_basic_imp.h"
18 extern const XFA_PACKETINFO g_XFAPacketData[];
19 extern const int32_t g_iXFAPacketCount;
20 extern const XFA_ATTRIBUTEENUMINFO g_XFAEnumData[];
21 extern const int32_t g_iXFAEnumCount;
22 extern const XFA_ATTRIBUTEINFO g_XFAAttributeData[];
23 extern const int32_t g_iXFAAttributeCount;
24 extern const XFA_ELEMENTINFO g_XFAElementData[];
25 extern const int32_t g_iXFAElementCount;
26 extern const XFA_ELEMENTHIERARCHY g_XFAElementChildrenIndex[];
27 extern const FX_WORD g_XFAElementChildrenData[];
28 extern const XFA_ELEMENTHIERARCHY g_XFAElementAttributeIndex[];
29 extern const uint8_t g_XFAElementAttributeData[];
30 extern const XFA_NOTSUREATTRIBUTE g_XFANotsureAttributes[];
31 extern const int32_t g_iXFANotsureCount;
32 extern const XFA_ELEMENTHIERARCHY g_XFAElementPropertyIndex[];
33 extern const XFA_PROPERTY g_XFAElementPropertyData[];
34 extern const XFA_SCRIPTHIERARCHY g_XFAScriptIndex[];
35 extern const XFA_METHODINFO g_SomMethodData[];
36 extern const int32_t g_iSomMethodCount;
37 extern const XFA_SCRIPTATTRIBUTEINFO g_SomAttributeData[];
38 extern const int32_t g_iSomAttributeCount;
XFA_GetPacketByName(const CFX_WideStringC & wsName)39 XFA_LPCPACKETINFO XFA_GetPacketByName(const CFX_WideStringC& wsName) {
40   int32_t iLength = wsName.GetLength();
41   if (iLength == 0) {
42     return NULL;
43   }
44   uint32_t uHash = FX_HashCode_String_GetW(wsName.GetPtr(), iLength);
45   int32_t iStart = 0, iEnd = g_iXFAPacketCount - 1;
46   do {
47     int32_t iMid = (iStart + iEnd) / 2;
48     XFA_LPCPACKETINFO pInfo = g_XFAPacketData + iMid;
49     if (uHash == pInfo->uHash) {
50       return pInfo;
51     } else if (uHash < pInfo->uHash) {
52       iEnd = iMid - 1;
53     } else {
54       iStart = iMid + 1;
55     }
56   } while (iStart <= iEnd);
57   return NULL;
58 }
XFA_GetPacketByID(FX_DWORD dwPacket)59 XFA_LPCPACKETINFO XFA_GetPacketByID(FX_DWORD dwPacket) {
60   int32_t iStart = 0, iEnd = g_iXFAPacketCount - 1;
61   do {
62     int32_t iMid = (iStart + iEnd) / 2;
63     FX_DWORD dwFind = (g_XFAPacketData + iMid)->eName;
64     if (dwPacket == dwFind) {
65       return g_XFAPacketData + iMid;
66     } else if (dwPacket < dwFind) {
67       iEnd = iMid - 1;
68     } else {
69       iStart = iMid + 1;
70     }
71   } while (iStart <= iEnd);
72   return NULL;
73 }
XFA_GetAttributeEnumByName(const CFX_WideStringC & wsName)74 XFA_LPCATTRIBUTEENUMINFO XFA_GetAttributeEnumByName(
75     const CFX_WideStringC& wsName) {
76   int32_t iLength = wsName.GetLength();
77   if (iLength == 0) {
78     return NULL;
79   }
80   uint32_t uHash = FX_HashCode_String_GetW(wsName.GetPtr(), iLength);
81   int32_t iStart = 0, iEnd = g_iXFAEnumCount - 1;
82   do {
83     int32_t iMid = (iStart + iEnd) / 2;
84     XFA_LPCATTRIBUTEENUMINFO pInfo = g_XFAEnumData + iMid;
85     if (uHash == pInfo->uHash) {
86       return pInfo;
87     } else if (uHash < pInfo->uHash) {
88       iEnd = iMid - 1;
89     } else {
90       iStart = iMid + 1;
91     }
92   } while (iStart <= iEnd);
93   return NULL;
94 }
XFA_GetAttributeEnumByID(XFA_ATTRIBUTEENUM eName)95 XFA_LPCATTRIBUTEENUMINFO XFA_GetAttributeEnumByID(XFA_ATTRIBUTEENUM eName) {
96   return g_XFAEnumData + eName;
97 }
XFA_GetAttributeCount()98 int32_t XFA_GetAttributeCount() {
99   return g_iXFAAttributeCount;
100 }
XFA_GetAttributeByName(const CFX_WideStringC & wsName)101 XFA_LPCATTRIBUTEINFO XFA_GetAttributeByName(const CFX_WideStringC& wsName) {
102   int32_t iLength = wsName.GetLength();
103   if (iLength == 0) {
104     return NULL;
105   }
106   uint32_t uHash = FX_HashCode_String_GetW(wsName.GetPtr(), iLength);
107   int32_t iStart = 0, iEnd = g_iXFAAttributeCount - 1;
108   do {
109     int32_t iMid = (iStart + iEnd) / 2;
110     XFA_LPCATTRIBUTEINFO pInfo = g_XFAAttributeData + iMid;
111     if (uHash == pInfo->uHash) {
112       return pInfo;
113     } else if (uHash < pInfo->uHash) {
114       iEnd = iMid - 1;
115     } else {
116       iStart = iMid + 1;
117     }
118   } while (iStart <= iEnd);
119   return NULL;
120 }
XFA_GetAttributeByID(XFA_ATTRIBUTE eName)121 XFA_LPCATTRIBUTEINFO XFA_GetAttributeByID(XFA_ATTRIBUTE eName) {
122   return (eName < g_iXFAAttributeCount) ? (g_XFAAttributeData + eName) : NULL;
123 }
XFA_GetAttributeDefaultValue(void * & pValue,XFA_ELEMENT eElement,XFA_ATTRIBUTE eAttribute,XFA_ATTRIBUTETYPE eType,FX_DWORD dwPacket)124 FX_BOOL XFA_GetAttributeDefaultValue(void*& pValue,
125                                      XFA_ELEMENT eElement,
126                                      XFA_ATTRIBUTE eAttribute,
127                                      XFA_ATTRIBUTETYPE eType,
128                                      FX_DWORD dwPacket) {
129   XFA_LPCATTRIBUTEINFO pInfo = XFA_GetAttributeByID(eAttribute);
130   if (pInfo == NULL) {
131     return FALSE;
132   }
133   if (dwPacket && (dwPacket & pInfo->dwPackets) == 0) {
134     return FALSE;
135   }
136   if (pInfo->eType == eType) {
137     pValue = pInfo->pDefValue;
138     return TRUE;
139   } else if (pInfo->eType == XFA_ATTRIBUTETYPE_NOTSURE) {
140     XFA_LPCNOTSUREATTRIBUTE pAttr =
141         XFA_GetNotsureAttribute(eElement, eAttribute, eType);
142     if (pAttr) {
143       pValue = pAttr->pValue;
144       return TRUE;
145     }
146   }
147   return FALSE;
148 }
XFA_GetAttributeDefaultValue_Enum(XFA_ELEMENT eElement,XFA_ATTRIBUTE eAttribute,FX_DWORD dwPacket)149 XFA_ATTRIBUTEENUM XFA_GetAttributeDefaultValue_Enum(XFA_ELEMENT eElement,
150                                                     XFA_ATTRIBUTE eAttribute,
151                                                     FX_DWORD dwPacket) {
152   void* pValue;
153   if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute,
154                                    XFA_ATTRIBUTETYPE_Enum, dwPacket)) {
155     return (XFA_ATTRIBUTEENUM)(uintptr_t)pValue;
156   }
157   return XFA_ATTRIBUTEENUM_Unknown;
158 }
XFA_GetAttributeDefaultValue_Cdata(XFA_ELEMENT eElement,XFA_ATTRIBUTE eAttribute,FX_DWORD dwPacket)159 CFX_WideStringC XFA_GetAttributeDefaultValue_Cdata(XFA_ELEMENT eElement,
160                                                    XFA_ATTRIBUTE eAttribute,
161                                                    FX_DWORD dwPacket) {
162   void* pValue;
163   if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute,
164                                    XFA_ATTRIBUTETYPE_Cdata, dwPacket)) {
165     return (const FX_WCHAR*)pValue;
166   }
167   return NULL;
168 }
XFA_GetAttributeDefaultValue_Boolean(XFA_ELEMENT eElement,XFA_ATTRIBUTE eAttribute,FX_DWORD dwPacket)169 FX_BOOL XFA_GetAttributeDefaultValue_Boolean(XFA_ELEMENT eElement,
170                                              XFA_ATTRIBUTE eAttribute,
171                                              FX_DWORD dwPacket) {
172   void* pValue;
173   if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute,
174                                    XFA_ATTRIBUTETYPE_Boolean, dwPacket)) {
175     return (FX_BOOL)(uintptr_t)pValue;
176   }
177   return FALSE;
178 }
XFA_GetAttributeDefaultValue_Integer(XFA_ELEMENT eElement,XFA_ATTRIBUTE eAttribute,FX_DWORD dwPacket)179 int32_t XFA_GetAttributeDefaultValue_Integer(XFA_ELEMENT eElement,
180                                              XFA_ATTRIBUTE eAttribute,
181                                              FX_DWORD dwPacket) {
182   void* pValue;
183   if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute,
184                                    XFA_ATTRIBUTETYPE_Integer, dwPacket)) {
185     return (int32_t)(uintptr_t)pValue;
186   }
187   return 0;
188 }
XFA_GetAttributeDefaultValue_Measure(XFA_ELEMENT eElement,XFA_ATTRIBUTE eAttribute,FX_DWORD dwPacket)189 CXFA_Measurement XFA_GetAttributeDefaultValue_Measure(XFA_ELEMENT eElement,
190                                                       XFA_ATTRIBUTE eAttribute,
191                                                       FX_DWORD dwPacket) {
192   void* pValue;
193   if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute,
194                                    XFA_ATTRIBUTETYPE_Measure, dwPacket)) {
195     return *(CXFA_Measurement*)pValue;
196   }
197   return CXFA_Measurement();
198 }
XFA_GetElementCount()199 int32_t XFA_GetElementCount() {
200   return g_iXFAElementCount;
201 }
XFA_GetElementByName(const CFX_WideStringC & wsName)202 XFA_LPCELEMENTINFO XFA_GetElementByName(const CFX_WideStringC& wsName) {
203   int32_t iLength = wsName.GetLength();
204   if (iLength == 0) {
205     return NULL;
206   }
207   uint32_t uHash = FX_HashCode_String_GetW(wsName.GetPtr(), iLength);
208   int32_t iStart = 0, iEnd = g_iXFAElementCount - 1;
209   do {
210     int32_t iMid = (iStart + iEnd) / 2;
211     XFA_LPCELEMENTINFO pInfo = g_XFAElementData + iMid;
212     if (uHash == pInfo->uHash) {
213       return pInfo;
214     } else if (uHash < pInfo->uHash) {
215       iEnd = iMid - 1;
216     } else {
217       iStart = iMid + 1;
218     }
219   } while (iStart <= iEnd);
220   return NULL;
221 }
XFA_GetElementByID(XFA_ELEMENT eName)222 XFA_LPCELEMENTINFO XFA_GetElementByID(XFA_ELEMENT eName) {
223   return (eName < g_iXFAElementCount) ? (g_XFAElementData + eName) : NULL;
224 }
XFA_GetElementChildren(XFA_ELEMENT eElement,int32_t & iCount)225 const FX_WORD* XFA_GetElementChildren(XFA_ELEMENT eElement, int32_t& iCount) {
226   if (eElement >= g_iXFAElementCount) {
227     return NULL;
228   }
229   XFA_LPCELEMENTHIERARCHY pElement = g_XFAElementChildrenIndex + eElement;
230   iCount = pElement->wCount;
231   return g_XFAElementChildrenData + pElement->wStart;
232 }
XFA_GetElementAttributes(XFA_ELEMENT eElement,int32_t & iCount)233 const uint8_t* XFA_GetElementAttributes(XFA_ELEMENT eElement, int32_t& iCount) {
234   if (eElement >= g_iXFAElementCount) {
235     return NULL;
236   }
237   XFA_LPCELEMENTHIERARCHY pElement = g_XFAElementAttributeIndex + eElement;
238   iCount = pElement->wCount;
239   return g_XFAElementAttributeData + pElement->wStart;
240 }
XFA_GetAttributeOfElement(XFA_ELEMENT eElement,XFA_ATTRIBUTE eAttribute,FX_DWORD dwPacket)241 XFA_LPCATTRIBUTEINFO XFA_GetAttributeOfElement(XFA_ELEMENT eElement,
242                                                XFA_ATTRIBUTE eAttribute,
243                                                FX_DWORD dwPacket) {
244   int32_t iCount = 0;
245   const uint8_t* pAttr = XFA_GetElementAttributes(eElement, iCount);
246   if (pAttr == NULL || iCount < 1) {
247     return NULL;
248   }
249   CFX_DSPATemplate<uint8_t> search;
250   int32_t index = search.Lookup(eAttribute, pAttr, iCount);
251   if (index < 0) {
252     return NULL;
253   }
254   XFA_LPCATTRIBUTEINFO pInfo = XFA_GetAttributeByID(eAttribute);
255   ASSERT(pInfo != NULL);
256   if (dwPacket == XFA_XDPPACKET_UNKNOWN) {
257     return pInfo;
258   }
259   return (dwPacket & pInfo->dwPackets) ? pInfo : NULL;
260 }
XFA_GetChildOfElement(XFA_ELEMENT eElement,XFA_ELEMENT eChild,FX_DWORD dwPacket)261 XFA_LPCELEMENTINFO XFA_GetChildOfElement(XFA_ELEMENT eElement,
262                                          XFA_ELEMENT eChild,
263                                          FX_DWORD dwPacket) {
264   int32_t iCount = 0;
265   const FX_WORD* pChild = XFA_GetElementChildren(eElement, iCount);
266   if (pChild == NULL || iCount < 1) {
267     return NULL;
268   }
269   CFX_DSPATemplate<FX_WORD> search;
270   int32_t index = search.Lookup(eChild, pChild, iCount);
271   if (index < 0) {
272     return NULL;
273   }
274   XFA_LPCELEMENTINFO pInfo = XFA_GetElementByID(eChild);
275   ASSERT(pInfo != NULL);
276   if (dwPacket == XFA_XDPPACKET_UNKNOWN) {
277     return pInfo;
278   }
279   return (dwPacket & pInfo->dwPackets) ? pInfo : NULL;
280 }
XFA_GetElementProperties(XFA_ELEMENT eElement,int32_t & iCount)281 XFA_LPCPROPERTY XFA_GetElementProperties(XFA_ELEMENT eElement,
282                                          int32_t& iCount) {
283   if (eElement >= g_iXFAElementCount) {
284     return NULL;
285   }
286   XFA_LPCELEMENTHIERARCHY pElement = g_XFAElementPropertyIndex + eElement;
287   iCount = pElement->wCount;
288   return g_XFAElementPropertyData + pElement->wStart;
289 }
XFA_GetPropertyOfElement(XFA_ELEMENT eElement,XFA_ELEMENT eProperty,FX_DWORD dwPacket)290 XFA_LPCPROPERTY XFA_GetPropertyOfElement(XFA_ELEMENT eElement,
291                                          XFA_ELEMENT eProperty,
292                                          FX_DWORD dwPacket) {
293   int32_t iCount = 0;
294   XFA_LPCPROPERTY pProperty = XFA_GetElementProperties(eElement, iCount);
295   if (pProperty == NULL || iCount < 1) {
296     return NULL;
297   }
298   int32_t iStart = 0, iEnd = iCount - 1, iMid;
299   do {
300     iMid = (iStart + iEnd) / 2;
301     XFA_ELEMENT eName = (XFA_ELEMENT)pProperty[iMid].eName;
302     if (eProperty == eName) {
303       break;
304     } else if (eProperty < eName) {
305       iEnd = iMid - 1;
306     } else {
307       iStart = iMid + 1;
308     }
309   } while (iStart <= iEnd);
310   if (iStart > iEnd) {
311     return NULL;
312   }
313   XFA_LPCELEMENTINFO pInfo = XFA_GetElementByID(eProperty);
314   ASSERT(pInfo != NULL);
315   if (dwPacket == XFA_XDPPACKET_UNKNOWN) {
316     return pProperty + iMid;
317   }
318   return (dwPacket & pInfo->dwPackets) ? (pProperty + iMid) : NULL;
319 }
XFA_GetNotsureAttribute(XFA_ELEMENT eElement,XFA_ATTRIBUTE eAttribute,XFA_ATTRIBUTETYPE eType)320 XFA_LPCNOTSUREATTRIBUTE XFA_GetNotsureAttribute(XFA_ELEMENT eElement,
321                                                 XFA_ATTRIBUTE eAttribute,
322                                                 XFA_ATTRIBUTETYPE eType) {
323   int32_t iStart = 0, iEnd = g_iXFANotsureCount - 1;
324   do {
325     int32_t iMid = (iStart + iEnd) / 2;
326     XFA_LPCNOTSUREATTRIBUTE pAttr = g_XFANotsureAttributes + iMid;
327     if (eElement == pAttr->eElement) {
328       if (pAttr->eAttribute == eAttribute) {
329         if (eType == XFA_ATTRIBUTETYPE_NOTSURE || eType == pAttr->eType) {
330           return pAttr;
331         }
332         return NULL;
333       } else {
334         int32_t iBefore = iMid - 1;
335         if (iBefore >= 0) {
336           pAttr = g_XFANotsureAttributes + iBefore;
337           while (eElement == pAttr->eElement) {
338             if (pAttr->eAttribute == eAttribute) {
339               if (eType == XFA_ATTRIBUTETYPE_NOTSURE || eType == pAttr->eType) {
340                 return pAttr;
341               }
342               return NULL;
343             }
344             iBefore--;
345             if (iBefore < 0) {
346               break;
347             }
348             pAttr = g_XFANotsureAttributes + iBefore;
349           }
350         }
351         int32_t iAfter = iMid + 1;
352         if (iAfter <= g_iXFANotsureCount - 1) {
353           pAttr = g_XFANotsureAttributes + iAfter;
354           while (eElement == pAttr->eElement) {
355             if (pAttr->eAttribute == eAttribute) {
356               if (eType == XFA_ATTRIBUTETYPE_NOTSURE || eType == pAttr->eType) {
357                 return pAttr;
358               }
359               return NULL;
360             }
361             iAfter++;
362             if (iAfter > g_iXFANotsureCount - 1) {
363               break;
364             }
365             pAttr = g_XFANotsureAttributes + iAfter;
366           }
367         }
368         return NULL;
369       }
370     } else if (eElement < pAttr->eElement) {
371       iEnd = iMid - 1;
372     } else {
373       iStart = iMid + 1;
374     }
375   } while (iStart <= iEnd);
376   return NULL;
377 }
XFA_GetMethodCount()378 int32_t XFA_GetMethodCount() {
379   return g_iSomMethodCount;
380 }
XFA_GetMethodByName(XFA_ELEMENT eElement,const CFX_WideStringC & wsMethodName)381 XFA_LPCMETHODINFO XFA_GetMethodByName(XFA_ELEMENT eElement,
382                                       const CFX_WideStringC& wsMethodName) {
383   int32_t iLength = wsMethodName.GetLength();
384   if (iLength == 0) {
385     return NULL;
386   }
387   int32_t iElementIndex = eElement;
388   while (iElementIndex != -1) {
389     XFA_LPCSCRIPTHIERARCHY scriptIndex = g_XFAScriptIndex + iElementIndex;
390     int32_t icount = scriptIndex->wMethodCount;
391     if (icount == 0) {
392       iElementIndex = scriptIndex->wParentIndex;
393       continue;
394     }
395     uint32_t uHash = FX_HashCode_String_GetW(wsMethodName.GetPtr(), iLength);
396     int32_t iStart = scriptIndex->wMethodStart, iEnd = iStart + icount - 1;
397     do {
398       int32_t iMid = (iStart + iEnd) / 2;
399       XFA_LPCMETHODINFO pInfo = g_SomMethodData + iMid;
400       if (uHash == pInfo->uHash) {
401         return pInfo;
402       } else if (uHash < pInfo->uHash) {
403         iEnd = iMid - 1;
404       } else {
405         iStart = iMid + 1;
406       }
407     } while (iStart <= iEnd);
408     iElementIndex = scriptIndex->wParentIndex;
409   }
410   return NULL;
411 }
XFA_GetScriptAttributeByName(XFA_ELEMENT eElement,const CFX_WideStringC & wsAttributeName)412 XFA_LPCSCRIPTATTRIBUTEINFO XFA_GetScriptAttributeByName(
413     XFA_ELEMENT eElement,
414     const CFX_WideStringC& wsAttributeName) {
415   int32_t iLength = wsAttributeName.GetLength();
416   if (iLength == 0) {
417     return NULL;
418   }
419   int32_t iElementIndex = eElement;
420   while (iElementIndex != -1) {
421     XFA_LPCSCRIPTHIERARCHY scriptIndex = g_XFAScriptIndex + iElementIndex;
422     int32_t icount = scriptIndex->wAttributeCount;
423     if (icount == 0) {
424       iElementIndex = scriptIndex->wParentIndex;
425       continue;
426     }
427     uint32_t uHash = FX_HashCode_String_GetW(wsAttributeName.GetPtr(), iLength);
428     int32_t iStart = scriptIndex->wAttributeStart, iEnd = iStart + icount - 1;
429     do {
430       int32_t iMid = (iStart + iEnd) / 2;
431       XFA_LPCSCRIPTATTRIBUTEINFO pInfo = g_SomAttributeData + iMid;
432       if (uHash == pInfo->uHash) {
433         return pInfo;
434       } else if (uHash < pInfo->uHash) {
435         iEnd = iMid - 1;
436       } else {
437         iStart = iMid + 1;
438       }
439     } while (iStart <= iEnd);
440     iElementIndex = scriptIndex->wParentIndex;
441   }
442   return NULL;
443 }
Set(const CFX_WideStringC & wsMeasure)444 void CXFA_Measurement::Set(const CFX_WideStringC& wsMeasure) {
445   if (wsMeasure.IsEmpty()) {
446     m_fValue = 0;
447     m_eUnit = XFA_UNIT_Unknown;
448     return;
449   }
450   int32_t iUsedLen = 0;
451   int32_t iOffset = (wsMeasure.GetAt(0) == L'=') ? 1 : 0;
452   FX_FLOAT fValue = FX_wcstof(wsMeasure.GetPtr() + iOffset,
453                               wsMeasure.GetLength() - iOffset, &iUsedLen);
454   XFA_UNIT eUnit = GetUnit(wsMeasure.Mid(iOffset + iUsedLen));
455   Set(fValue, eUnit);
456 }
ToString(CFX_WideString & wsMeasure) const457 FX_BOOL CXFA_Measurement::ToString(CFX_WideString& wsMeasure) const {
458   switch (GetUnit()) {
459     case XFA_UNIT_Mm:
460       wsMeasure.Format(L"%.8gmm", GetValue());
461       return TRUE;
462     case XFA_UNIT_Pt:
463       wsMeasure.Format(L"%.8gpt", GetValue());
464       return TRUE;
465     case XFA_UNIT_In:
466       wsMeasure.Format(L"%.8gin", GetValue());
467       return TRUE;
468     case XFA_UNIT_Cm:
469       wsMeasure.Format(L"%.8gcm", GetValue());
470       return TRUE;
471     case XFA_UNIT_Mp:
472       wsMeasure.Format(L"%.8gmp", GetValue());
473       return TRUE;
474     case XFA_UNIT_Pc:
475       wsMeasure.Format(L"%.8gpc", GetValue());
476       return TRUE;
477     case XFA_UNIT_Em:
478       wsMeasure.Format(L"%.8gem", GetValue());
479       return TRUE;
480     case XFA_UNIT_Percent:
481       wsMeasure.Format(L"%.8g%%", GetValue());
482       return TRUE;
483     default:
484       wsMeasure.Format(L"%.8g", GetValue());
485       return FALSE;
486   }
487 }
ToUnit(XFA_UNIT eUnit,FX_FLOAT & fValue) const488 FX_BOOL CXFA_Measurement::ToUnit(XFA_UNIT eUnit, FX_FLOAT& fValue) const {
489   fValue = GetValue();
490   XFA_UNIT eFrom = GetUnit();
491   if (eFrom == eUnit) {
492     return TRUE;
493   }
494   switch (eFrom) {
495     case XFA_UNIT_Pt:
496       break;
497     case XFA_UNIT_Mm:
498       fValue *= 72 / 2.54f / 10;
499       break;
500     case XFA_UNIT_In:
501       fValue *= 72;
502       break;
503     case XFA_UNIT_Cm:
504       fValue *= 72 / 2.54f;
505       break;
506     case XFA_UNIT_Mp:
507       fValue *= 0.001f;
508       break;
509     case XFA_UNIT_Pc:
510       fValue *= 12.0f;
511       break;
512     default:
513       fValue = 0;
514       return FALSE;
515   }
516   switch (eUnit) {
517     case XFA_UNIT_Pt:
518       return TRUE;
519     case XFA_UNIT_Mm:
520       fValue /= 72 / 2.54f / 10;
521       return TRUE;
522     case XFA_UNIT_In:
523       fValue /= 72;
524       return TRUE;
525     case XFA_UNIT_Cm:
526       fValue /= 72 / 2.54f;
527       return TRUE;
528     case XFA_UNIT_Mp:
529       fValue /= 0.001f;
530       return TRUE;
531     case XFA_UNIT_Pc:
532       fValue /= 12.0f;
533       return TRUE;
534     default:
535       fValue = 0;
536       return FALSE;
537   }
538   return FALSE;
539 }
GetUnit(const CFX_WideStringC & wsUnit)540 XFA_UNIT CXFA_Measurement::GetUnit(const CFX_WideStringC& wsUnit) {
541   if (wsUnit == FX_WSTRC(L"mm")) {
542     return XFA_UNIT_Mm;
543   } else if (wsUnit == FX_WSTRC(L"pt")) {
544     return XFA_UNIT_Pt;
545   } else if (wsUnit == FX_WSTRC(L"in")) {
546     return XFA_UNIT_In;
547   } else if (wsUnit == FX_WSTRC(L"cm")) {
548     return XFA_UNIT_Cm;
549   } else if (wsUnit == FX_WSTRC(L"pc")) {
550     return XFA_UNIT_Pc;
551   } else if (wsUnit == FX_WSTRC(L"mp")) {
552     return XFA_UNIT_Mp;
553   } else if (wsUnit == FX_WSTRC(L"em")) {
554     return XFA_UNIT_Em;
555   } else if (wsUnit == FX_WSTRC(L"%")) {
556     return XFA_UNIT_Percent;
557   } else {
558     return XFA_UNIT_Unknown;
559   }
560 }
XFA_CreateWideTextRead(const CFX_WideString & wsBuffer)561 IFX_Stream* XFA_CreateWideTextRead(const CFX_WideString& wsBuffer) {
562   return new CXFA_WideTextRead(wsBuffer);
563 }
CXFA_WideTextRead(const CFX_WideString & wsBuffer)564 CXFA_WideTextRead::CXFA_WideTextRead(const CFX_WideString& wsBuffer)
565     : m_wsBuffer(wsBuffer), m_iPosition(0), m_iRefCount(1) {}
Release()566 void CXFA_WideTextRead::Release() {
567   if (--m_iRefCount < 1) {
568     delete this;
569   }
570 }
Retain()571 IFX_Stream* CXFA_WideTextRead::Retain() {
572   m_iRefCount++;
573   return this;
574 }
GetAccessModes() const575 FX_DWORD CXFA_WideTextRead::GetAccessModes() const {
576   return FX_STREAMACCESS_Read | FX_STREAMACCESS_Text;
577 }
GetLength() const578 int32_t CXFA_WideTextRead::GetLength() const {
579   return m_wsBuffer.GetLength() * sizeof(FX_WCHAR);
580 }
Seek(FX_STREAMSEEK eSeek,int32_t iOffset)581 int32_t CXFA_WideTextRead::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) {
582   switch (eSeek) {
583     case FX_STREAMSEEK_Begin:
584       m_iPosition = iOffset;
585       break;
586     case FX_STREAMSEEK_Current:
587       m_iPosition += iOffset;
588       break;
589     case FX_STREAMSEEK_End:
590       m_iPosition = m_wsBuffer.GetLength() + iOffset;
591       break;
592   }
593   if (m_iPosition < 0) {
594     m_iPosition = 0;
595   }
596   if (m_iPosition > m_wsBuffer.GetLength()) {
597     m_iPosition = m_wsBuffer.GetLength();
598   }
599   return GetPosition();
600 }
GetPosition()601 int32_t CXFA_WideTextRead::GetPosition() {
602   return m_iPosition * sizeof(FX_WCHAR);
603 }
IsEOF() const604 FX_BOOL CXFA_WideTextRead::IsEOF() const {
605   return m_iPosition >= m_wsBuffer.GetLength();
606 }
ReadString(FX_WCHAR * pStr,int32_t iMaxLength,FX_BOOL & bEOS,int32_t const * pByteSize)607 int32_t CXFA_WideTextRead::ReadString(FX_WCHAR* pStr,
608                                       int32_t iMaxLength,
609                                       FX_BOOL& bEOS,
610                                       int32_t const* pByteSize) {
611   if (iMaxLength > m_wsBuffer.GetLength() - m_iPosition) {
612     iMaxLength = m_wsBuffer.GetLength() - m_iPosition;
613   }
614   FXSYS_wcsncpy(pStr, (const FX_WCHAR*)m_wsBuffer + m_iPosition, iMaxLength);
615   m_iPosition += iMaxLength;
616   bEOS = IsEOF();
617   return iMaxLength;
618 }
GetCodePage() const619 FX_WORD CXFA_WideTextRead::GetCodePage() const {
620   return (sizeof(FX_WCHAR) == 2) ? FX_CODEPAGE_UTF16LE : FX_CODEPAGE_UTF32LE;
621 }
SetCodePage(FX_WORD wCodePage)622 FX_WORD CXFA_WideTextRead::SetCodePage(FX_WORD wCodePage) {
623   return GetCodePage();
624 }
625