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 "core/include/fxcrt/fx_xml.h" 8#include "xfa/src/foxitlib.h" 9#include "xfa/src/fxfa/src/common/xfa_utils.h" 10#include "xfa/src/fxfa/src/common/xfa_object.h" 11#include "xfa/src/fxfa/src/common/xfa_document.h" 12#include "xfa/src/fxfa/src/common/xfa_parser.h" 13#include "xfa/src/fxfa/src/common/xfa_script.h" 14#include "xfa/src/fxfa/src/common/xfa_docdata.h" 15#include "xfa/src/fxfa/src/common/xfa_doclayout.h" 16#include "xfa/src/fxfa/src/common/xfa_localemgr.h" 17#include "xfa/src/fxfa/src/common/xfa_fm2jsapi.h" 18#include "xfa_locale.h" 19 20static const FX_WCHAR* g_FX_Percent = L"z,zzz,zzz,zzz,zzz,zzz%"; 21static const FX_WCHAR* g_FX_Currency = L"$z,zzz,zzz,zzz,zzz,zz9.99"; 22static const FX_WCHAR* g_FX_Decimal = L"z,zzz,zzz,zzz,zzz,zz9.zzz"; 23static const FX_WCHAR* g_FX_Integer = L"z,zzz,zzz,zzz,zzz,zzz"; 24CXFA_XMLLocale::CXFA_XMLLocale(CXML_Element* pLocaleData) { 25 m_pLocaleData = pLocaleData; 26} 27CXFA_XMLLocale::~CXFA_XMLLocale() { 28 if (m_pLocaleData) { 29 delete m_pLocaleData; 30 } 31} 32void CXFA_XMLLocale::Release() { 33 delete this; 34} 35CFX_WideString CXFA_XMLLocale::GetName() { 36 return m_pLocaleData ? m_pLocaleData->GetAttrValue("name") : CFX_WideString(); 37} 38void CXFA_XMLLocale::GetNumbericSymbol(FX_LOCALENUMSYMBOL eType, 39 CFX_WideString& wsNumSymbol) const { 40 CFX_ByteString bsSymbols; 41 CFX_WideString wsName; 42 switch (eType) { 43 case FX_LOCALENUMSYMBOL_Decimal: 44 bsSymbols = "numberSymbols"; 45 wsName = FX_WSTRC(L"decimal"); 46 break; 47 case FX_LOCALENUMSYMBOL_Grouping: 48 bsSymbols = "numberSymbols"; 49 wsName = FX_WSTRC(L"grouping"); 50 break; 51 case FX_LOCALENUMSYMBOL_Percent: 52 bsSymbols = "numberSymbols"; 53 wsName = FX_WSTRC(L"percent"); 54 break; 55 case FX_LOCALENUMSYMBOL_Minus: 56 bsSymbols = "numberSymbols"; 57 wsName = FX_WSTRC(L"minus"); 58 break; 59 case FX_LOCALENUMSYMBOL_Zero: 60 bsSymbols = "numberSymbols"; 61 wsName = FX_WSTRC(L"zero"); 62 break; 63 case FX_LOCALENUMSYMBOL_CurrencySymbol: 64 bsSymbols = "currencySymbols"; 65 wsName = FX_WSTRC(L"symbol"); 66 break; 67 case FX_LOCALENUMSYMBOL_CurrencyName: 68 bsSymbols = "currencySymbols"; 69 wsName = FX_WSTRC(L"isoname"); 70 break; 71 default: 72 return; 73 } 74 CXML_Element* pElement = m_pLocaleData->GetElement("", bsSymbols); 75 if (!pElement) { 76 return; 77 } 78 GetPattern(pElement, CFX_ByteStringC((const FX_CHAR*)bsSymbols, 79 bsSymbols.GetLength() - 1), 80 wsName, wsNumSymbol); 81} 82void CXFA_XMLLocale::GetDateTimeSymbols(CFX_WideString& wsDtSymbol) const { 83 if (!m_pLocaleData) { 84 return; 85 } 86 CFX_ByteString bsSpace; 87 CXML_Element* pNumberSymbols = 88 m_pLocaleData->GetElement(bsSpace, "dateTimeSymbols"); 89 if (!pNumberSymbols) { 90 return; 91 } 92 wsDtSymbol = pNumberSymbols->GetContent(0); 93} 94void CXFA_XMLLocale::GetMonthName(int32_t nMonth, 95 CFX_WideString& wsMonthName, 96 FX_BOOL bAbbr) const { 97 wsMonthName = GetCalendarSymbol("month", nMonth, bAbbr); 98} 99void CXFA_XMLLocale::GetDayName(int32_t nWeek, 100 CFX_WideString& wsDayName, 101 FX_BOOL bAbbr) const { 102 wsDayName = GetCalendarSymbol("day", nWeek, bAbbr); 103} 104void CXFA_XMLLocale::GetMeridiemName(CFX_WideString& wsMeridiemName, 105 FX_BOOL bAM) const { 106 wsMeridiemName = GetCalendarSymbol("meridiem", bAM ? 0 : 1, FALSE); 107} 108void CXFA_XMLLocale::GetTimeZone(FX_TIMEZONE& tz) const { 109 IXFA_TimeZoneProvider* pProvider = IXFA_TimeZoneProvider::Get(); 110 pProvider->GetTimeZone(tz); 111} 112void CXFA_XMLLocale::GetEraName(CFX_WideString& wsEraName, FX_BOOL bAD) const { 113 wsEraName = GetCalendarSymbol("era", bAD ? 1 : 0, FALSE); 114} 115CFX_WideString CXFA_XMLLocale::GetCalendarSymbol(const CFX_ByteStringC& symbol, 116 int index, 117 FX_BOOL bAbbr) const { 118 CFX_ByteString pstrSymbolNames = symbol + "Names"; 119 CFX_WideString wsSymbolName = L""; 120 if (m_pLocaleData) { 121 CXML_Element* pChild = m_pLocaleData->GetElement("", "calendarSymbols"); 122 if (pChild) { 123 CXML_Element* pSymbolNames = pChild->GetElement("", pstrSymbolNames); 124 if (pSymbolNames) { 125 if (pSymbolNames->GetAttrInteger("abbr") != bAbbr) { 126 pSymbolNames = pChild->GetElement("", pstrSymbolNames, 1); 127 } 128 if (pSymbolNames && pSymbolNames->GetAttrInteger("abbr") == bAbbr) { 129 CXML_Element* pSymbolName = 130 pSymbolNames->GetElement("", symbol, index); 131 if (pSymbolName) { 132 wsSymbolName = pSymbolName->GetContent(0); 133 } 134 } 135 } 136 } 137 } 138 return wsSymbolName; 139} 140void CXFA_XMLLocale::GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY eType, 141 CFX_WideString& wsPattern) const { 142 CXML_Element* pElement = m_pLocaleData->GetElement("", "datePatterns"); 143 if (pElement == NULL) { 144 return; 145 } 146 CFX_WideString wsName; 147 switch (eType) { 148 case FX_LOCALEDATETIMESUBCATEGORY_Short: 149 wsName = L"short"; 150 break; 151 case FX_LOCALEDATETIMESUBCATEGORY_Default: 152 case FX_LOCALEDATETIMESUBCATEGORY_Medium: 153 wsName = L"med"; 154 break; 155 case FX_LOCALEDATETIMESUBCATEGORY_Full: 156 wsName = L"full"; 157 break; 158 case FX_LOCALEDATETIMESUBCATEGORY_Long: 159 wsName = L"long"; 160 break; 161 } 162 GetPattern(pElement, "datePattern", wsName, wsPattern); 163} 164void CXFA_XMLLocale::GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY eType, 165 CFX_WideString& wsPattern) const { 166 CXML_Element* pElement = m_pLocaleData->GetElement("", "timePatterns"); 167 if (pElement == NULL) { 168 return; 169 } 170 CFX_WideString wsName; 171 switch (eType) { 172 case FX_LOCALEDATETIMESUBCATEGORY_Short: 173 wsName = L"short"; 174 break; 175 case FX_LOCALEDATETIMESUBCATEGORY_Default: 176 case FX_LOCALEDATETIMESUBCATEGORY_Medium: 177 wsName = L"med"; 178 break; 179 case FX_LOCALEDATETIMESUBCATEGORY_Full: 180 wsName = L"full"; 181 break; 182 case FX_LOCALEDATETIMESUBCATEGORY_Long: 183 wsName = L"long"; 184 break; 185 } 186 GetPattern(pElement, "timePattern", wsName, wsPattern); 187} 188void CXFA_XMLLocale::GetNumPattern(FX_LOCALENUMSUBCATEGORY eType, 189 CFX_WideString& wsPattern) const { 190 CXML_Element* pElement = m_pLocaleData->GetElement("", "numberPatterns"); 191 if (pElement == NULL) { 192 return; 193 } 194 switch (eType) { 195 case FX_LOCALENUMPATTERN_Percent: 196 wsPattern = g_FX_Percent; 197 break; 198 case FX_LOCALENUMPATTERN_Currency: 199 wsPattern = g_FX_Currency; 200 break; 201 case FX_LOCALENUMPATTERN_Decimal: 202 wsPattern = g_FX_Decimal; 203 break; 204 case FX_LOCALENUMPATTERN_Integer: 205 wsPattern = g_FX_Integer; 206 break; 207 } 208} 209void CXFA_XMLLocale::GetPattern(CXML_Element* pElement, 210 const CFX_ByteStringC& bsTag, 211 const CFX_WideStringC& wsName, 212 CFX_WideString& wsPattern) const { 213 int32_t iCount = pElement->CountElements("", bsTag); 214 for (int32_t i = 0; i < iCount; i++) { 215 CXML_Element* pChild = pElement->GetElement("", bsTag, i); 216 if (pChild->GetAttrValue("name") == wsName) { 217 wsPattern = pChild->GetContent(0); 218 return; 219 } 220 } 221} 222CXFA_NodeLocale::CXFA_NodeLocale(CXFA_Node* pLocale) { 223 m_pLocale = pLocale; 224} 225CXFA_NodeLocale::~CXFA_NodeLocale() {} 226void CXFA_NodeLocale::Release() { 227 delete this; 228} 229CFX_WideString CXFA_NodeLocale::GetName() { 230 return m_pLocale ? m_pLocale->GetCData(XFA_ATTRIBUTE_Name) : NULL; 231} 232void CXFA_NodeLocale::GetNumbericSymbol(FX_LOCALENUMSYMBOL eType, 233 CFX_WideString& wsNumSymbol) const { 234 switch (eType) { 235 case FX_LOCALENUMSYMBOL_Decimal: 236 wsNumSymbol = GetSymbol(XFA_ELEMENT_NumberSymbols, FX_WSTRC(L"decimal")); 237 break; 238 case FX_LOCALENUMSYMBOL_Grouping: 239 wsNumSymbol = GetSymbol(XFA_ELEMENT_NumberSymbols, FX_WSTRC(L"grouping")); 240 break; 241 case FX_LOCALENUMSYMBOL_Percent: 242 wsNumSymbol = GetSymbol(XFA_ELEMENT_NumberSymbols, FX_WSTRC(L"percent")); 243 break; 244 case FX_LOCALENUMSYMBOL_Minus: 245 wsNumSymbol = GetSymbol(XFA_ELEMENT_NumberSymbols, FX_WSTRC(L"minus")); 246 break; 247 case FX_LOCALENUMSYMBOL_Zero: 248 wsNumSymbol = GetSymbol(XFA_ELEMENT_NumberSymbols, FX_WSTRC(L"zero")); 249 break; 250 case FX_LOCALENUMSYMBOL_CurrencySymbol: 251 wsNumSymbol = GetSymbol(XFA_ELEMENT_CurrencySymbols, FX_WSTRC(L"symbol")); 252 break; 253 case FX_LOCALENUMSYMBOL_CurrencyName: 254 wsNumSymbol = 255 GetSymbol(XFA_ELEMENT_CurrencySymbols, FX_WSTRC(L"isoname")); 256 break; 257 } 258} 259void CXFA_NodeLocale::GetDateTimeSymbols(CFX_WideString& wsDtSymbol) const { 260 CXFA_Node* pSymbols = 261 m_pLocale ? m_pLocale->GetChild(0, XFA_ELEMENT_DateTimeSymbols) : NULL; 262 wsDtSymbol = pSymbols ? pSymbols->GetContent() : CFX_WideString(); 263} 264void CXFA_NodeLocale::GetMonthName(int32_t nMonth, 265 CFX_WideString& wsMonthName, 266 FX_BOOL bAbbr) const { 267 wsMonthName = GetCalendarSymbol(XFA_ELEMENT_MonthNames, nMonth, bAbbr); 268} 269void CXFA_NodeLocale::GetDayName(int32_t nWeek, 270 CFX_WideString& wsDayName, 271 FX_BOOL bAbbr) const { 272 wsDayName = GetCalendarSymbol(XFA_ELEMENT_DayNames, nWeek, bAbbr); 273} 274void CXFA_NodeLocale::GetMeridiemName(CFX_WideString& wsMeridiemName, 275 FX_BOOL bAM) const { 276 wsMeridiemName = 277 GetCalendarSymbol(XFA_ELEMENT_MeridiemNames, bAM ? 0 : 1, FALSE); 278} 279void CXFA_NodeLocale::GetTimeZone(FX_TIMEZONE& tz) const { 280 IXFA_TimeZoneProvider* pProvider = IXFA_TimeZoneProvider::Get(); 281 pProvider->GetTimeZone(tz); 282} 283void CXFA_NodeLocale::GetEraName(CFX_WideString& wsEraName, FX_BOOL bAD) const { 284 wsEraName = GetCalendarSymbol(XFA_ELEMENT_EraNames, bAD ? 1 : 0, FALSE); 285} 286void CXFA_NodeLocale::GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY eType, 287 CFX_WideString& wsPattern) const { 288 switch (eType) { 289 case FX_LOCALEDATETIMESUBCATEGORY_Short: 290 wsPattern = GetSymbol(XFA_ELEMENT_DatePatterns, FX_WSTRC(L"short")); 291 break; 292 case FX_LOCALEDATETIMESUBCATEGORY_Medium: 293 case FX_LOCALEDATETIMESUBCATEGORY_Default: 294 wsPattern = GetSymbol(XFA_ELEMENT_DatePatterns, FX_WSTRC(L"med")); 295 break; 296 case FX_LOCALEDATETIMESUBCATEGORY_Full: 297 wsPattern = GetSymbol(XFA_ELEMENT_DatePatterns, FX_WSTRC(L"full")); 298 break; 299 case FX_LOCALEDATETIMESUBCATEGORY_Long: 300 wsPattern = GetSymbol(XFA_ELEMENT_DatePatterns, FX_WSTRC(L"long")); 301 break; 302 } 303} 304void CXFA_NodeLocale::GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY eType, 305 CFX_WideString& wsPattern) const { 306 switch (eType) { 307 case FX_LOCALEDATETIMESUBCATEGORY_Short: 308 wsPattern = GetSymbol(XFA_ELEMENT_TimePatterns, FX_WSTRC(L"short")); 309 break; 310 case FX_LOCALEDATETIMESUBCATEGORY_Medium: 311 case FX_LOCALEDATETIMESUBCATEGORY_Default: 312 wsPattern = GetSymbol(XFA_ELEMENT_TimePatterns, FX_WSTRC(L"med")); 313 break; 314 case FX_LOCALEDATETIMESUBCATEGORY_Full: 315 wsPattern = GetSymbol(XFA_ELEMENT_TimePatterns, FX_WSTRC(L"full")); 316 break; 317 case FX_LOCALEDATETIMESUBCATEGORY_Long: 318 wsPattern = GetSymbol(XFA_ELEMENT_TimePatterns, FX_WSTRC(L"long")); 319 break; 320 } 321} 322void CXFA_NodeLocale::GetNumPattern(FX_LOCALENUMSUBCATEGORY eType, 323 CFX_WideString& wsPattern) const { 324 switch (eType) { 325 case FX_LOCALENUMPATTERN_Percent: 326 wsPattern = g_FX_Percent; 327 break; 328 case FX_LOCALENUMPATTERN_Currency: 329 wsPattern = g_FX_Currency; 330 break; 331 case FX_LOCALENUMPATTERN_Decimal: 332 wsPattern = g_FX_Decimal; 333 break; 334 case FX_LOCALENUMPATTERN_Integer: 335 wsPattern = g_FX_Integer; 336 break; 337 } 338} 339CXFA_Node* CXFA_NodeLocale::GetNodeByName(CXFA_Node* pParent, 340 const CFX_WideStringC& wsName) const { 341 CXFA_Node* pChild = 342 pParent ? pParent->GetNodeItem(XFA_NODEITEM_FirstChild) : NULL; 343 while (pChild) { 344 CFX_WideString wsChild; 345 if (pChild->GetAttribute(XFA_ATTRIBUTE_Name, wsChild)) { 346 if (wsChild == wsName) { 347 return pChild; 348 } 349 } 350 pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling); 351 } 352 return NULL; 353} 354CFX_WideString CXFA_NodeLocale::GetSymbol( 355 XFA_ELEMENT eElement, 356 const CFX_WideStringC& symbol_type) const { 357 CXFA_Node* pSymbols = m_pLocale ? m_pLocale->GetChild(0, eElement) : NULL; 358 CXFA_Node* pSymbol = GetNodeByName(pSymbols, symbol_type); 359 return pSymbol ? pSymbol->GetContent() : CFX_WideString(); 360} 361CFX_WideString CXFA_NodeLocale::GetCalendarSymbol(XFA_ELEMENT eElement, 362 int index, 363 FX_BOOL bAbbr) const { 364 CXFA_Node* pCalendar = 365 m_pLocale ? m_pLocale->GetChild(0, XFA_ELEMENT_CalendarSymbols) : NULL; 366 if (pCalendar) { 367 CXFA_Node* pNode = pCalendar->GetFirstChildByClass(eElement); 368 for (; pNode; pNode = pNode->GetNextSameClassSibling(eElement)) { 369 if (pNode->GetBoolean(XFA_ATTRIBUTE_Abbr) == bAbbr) { 370 CXFA_Node* pSymbol = pNode->GetChild(index, XFA_ELEMENT_UNKNOWN); 371 return pSymbol ? pSymbol->GetContent() : CFX_WideString(); 372 } 373 } 374 } 375 return CFX_WideString(); 376} 377