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