uint16_t FX_GetCodePageBit(uint16_t wCodePage) { for (size_t i = 0; i < FX_ArraySize(g_Bit2CodePage); ++i) { if (g_Bit2CodePage[i].wCodePage == wCodePage) return g_Bit2CodePage[i].wBit; } return (uint16_t)-1; }
CPDF_Font* CPDF_Font::CreateFontF(CPDF_Document* pDoc, CPDF_Dictionary* pFontDict) { CFX_ByteString type = pFontDict->GetStringBy("Subtype"); std::unique_ptr<CPDF_Font> pFont; if (type == "TrueType") { CFX_ByteString tag = pFontDict->GetStringBy("BaseFont").Left(4); for (size_t i = 0; i < FX_ArraySize(kChineseFontNames); ++i) { if (tag == CFX_ByteString(kChineseFontNames[i], 4)) { CPDF_Dictionary* pFontDesc = pFontDict->GetDictBy("FontDescriptor"); if (!pFontDesc || !pFontDesc->KeyExist("FontFile2")) pFont.reset(new CPDF_CIDFont); break; } } if (!pFont) pFont.reset(new CPDF_TrueTypeFont); } else if (type == "Type3") { pFont.reset(new CPDF_Type3Font); } else if (type == "Type0") { pFont.reset(new CPDF_CIDFont); } else { pFont.reset(new CPDF_Type1Font); } pFont->m_pFontDict = pFontDict; pFont->m_pDocument = pDoc; pFont->m_BaseFont = pFontDict->GetStringBy("BaseFont"); return pFont->Load() ? pFont.release() : nullptr; }
TEST(PDF417HighLevelEncoder, ConsecutiveTextCount) { struct ConsecutiveTextCase { const wchar_t* input; int offset; int expected_count; } consecutive_text_cases[] = { // Empty string contains 0 consecutive text characters. {L"", 0, 0}, // Single text character is 1 consecutive text characters. {L"X", 0, 1}, // Trailing numbers count as text characters. {L"X123", 0, 4}, // Leading numbers count as text characters. {L"123X", 0, 4}, // Embedded lo-value binary characters terminate text runs. {L"ABC\x0001XXXX", 0, 3}, // Embedded hi-value binary characters terminate text runs. {L"ABC\x0100XXXX", 0, 3}, // Text run still found after indexing past lo-value character. {L"ABC\x0001XXXX", 4, 4}, // Text run still found after indexing past hi-value character. {L"ABC\x0100XXXX", 4, 4}, // Leading hi-value character results in 0 consecutive characters. {L"\x0100XXX", 0, 0}, // Up to 12 numbers count as text. {L"123456789012", 0, 12}, // 13 or more numbers are compresssed using numeric compression, not text. {L"1234567890123", 0, 0}, // Leading Text character doesn't affect the 12 character case. {L"X123456789012", 0, 13}, // Leading Text character doesn't affect the 13 character case. {L"X1234567890123", 0, 1}, // Jumping between numbers and letters works properly. {L"XXX121XXX12345678901234", 0, 9}, }; CBC_PDF417HighLevelEncoder::Initialize(); for (size_t i = 0; i < FX_ArraySize(consecutive_text_cases); ++i) { ConsecutiveTextCase* ptr = &consecutive_text_cases[i]; CFX_WideString input(ptr->input); int actual_count = CBC_PDF417HighLevelEncoder::determineConsecutiveTextCount(input, ptr->offset); EXPECT_EQ(ptr->expected_count, actual_count) << " for case number " << i; } CBC_PDF417HighLevelEncoder::Finalize(); }
CXFA_FWLTheme::CXFA_FWLTheme(CXFA_FFApp* pApp) : m_pCheckBoxTP(new CFWL_CheckBoxTP), m_pListBoxTP(new CFWL_ListBoxTP), m_pPictureBoxTP(new CFWL_PictureBoxTP), m_pSrollBarTP(new CFWL_ScrollBarTP), m_pEditTP(new CFWL_EditTP), m_pComboBoxTP(new CFWL_ComboBoxTP), m_pMonthCalendarTP(new CFWL_MonthCalendarTP), m_pDateTimePickerTP(new CFWL_DateTimePickerTP), m_pPushButtonTP(new CFWL_PushButtonTP), m_pCaretTP(new CFWL_CaretTP), m_pBarcodeTP(new CFWL_BarcodeTP), m_pTextOut(new CFDE_TextOut), m_fCapacity(0.0f), m_dwCapacity(0), m_pCalendarFont(nullptr), m_pApp(pApp) { m_Rect.Reset(); for (size_t i = 0; !m_pCalendarFont && i < FX_ArraySize(g_FWLTheme_CalFonts); ++i) { m_pCalendarFont = CFGAS_GEFont::LoadFont(g_FWLTheme_CalFonts[i], 0, 0, m_pApp->GetFDEFontMgr()); } if (!m_pCalendarFont) { m_pCalendarFont = m_pApp->GetFDEFontMgr()->GetFontByCodePage( FX_CODEPAGE_MSWin_WesternEuropean, 0, nullptr); } ASSERT(m_pCalendarFont); }
int CPDF_FontEncoding::CharCodeFromUnicode(wchar_t unicode) const { for (size_t i = 0; i < FX_ArraySize(m_Unicodes); i++) { if (m_Unicodes[i] == unicode) return i; } return -1; }
bool CFX_FontMgr::GetBuiltinFont(size_t index, const uint8_t** pFontData, uint32_t* size) { if (index < FX_ArraySize(g_FoxitFonts)) { *pFontData = g_FoxitFonts[index].m_pFontData; *size = g_FoxitFonts[index].m_dwSize; return true; } index -= FX_ArraySize(g_FoxitFonts); if (index < FX_ArraySize(g_MMFonts)) { *pFontData = g_MMFonts[index].m_pFontData; *size = g_MMFonts[index].m_dwSize; return true; } return false; }
TEST_F(CFGAS_FormatStringTest, DateTimeFormat) { struct { const wchar_t* locale; const wchar_t* input; const wchar_t* pattern; const wchar_t* output; } tests[] = { {L"en", L"1999-07-16T10:30Z", L"'At' time{HH:MM Z} 'on' date{MMM DD, YYYY}", L"At 10:30 GMT on Jul 16, 1999"}, {L"en", L"1999-07-16T10:30", L"'At' time{HH:MM} 'on' date{MMM DD, YYYY}", L"At 10:30 on Jul 16, 1999"}, {L"en", L"1999-07-16T10:30Z", L"time{'At' HH:MM Z} date{'on' MMM DD, YYYY}", L"At 10:30 GMT on Jul 16, 1999"}, {L"en", L"1999-07-16T10:30Z", L"time{'At 'HH:MM Z}date{' on 'MMM DD, YYYY}", L"At 10:30 GMT on Jul 16, 1999"}}; for (size_t i = 0; i < FX_ArraySize(tests); ++i) { WideString result; EXPECT_TRUE(fmt(tests[i].locale) ->FormatDateTime(tests[i].input, tests[i].pattern, FX_DATETIMETYPE_TimeDate, &result)); EXPECT_STREQ(tests[i].output, result.c_str()) << " TEST: " << i; } }
TEST_F(CFGAS_FormatStringTest, DateParse) { struct { const wchar_t* locale; const wchar_t* input; const wchar_t* pattern; CFX_DateTime output; } tests[] = { {L"en", L"12/2/99", L"MM/D/YY", CFX_DateTime(1999, 12, 2, 0, 0, 0, 0)}, {L"en", L"2/2/99", L"M/D/YY", CFX_DateTime(1999, 2, 2, 0, 0, 0, 0)}, {L"en", L"2/2/10", L"M/D/YY", CFX_DateTime(2010, 2, 2, 0, 0, 0, 0)}, {L"en", L"Jan 10, 1999", L"MMM D, YYYY", CFX_DateTime(1999, 1, 10, 0, 0, 0, 0)}, {L"en", L"Jan 10, 1999 AD", L"MMM D, YYYY G", CFX_DateTime(1999, 1, 10, 0, 0, 0, 0)}, // TODO(dsinclair): Should this be -2 instead of 2? {L"en", L"Jan 10, 0002 BC", L"MMM D, YYYY G", CFX_DateTime(2, 1, 10, 0, 0, 0, 0)}, {L"en", L"October 25, 2002", L"MMMM DD, YYYY", CFX_DateTime(2002, 10, 25, 0, 0, 0, 0)}, // TODO(dsinclair): The J and JJJ are ignored during parsing when they // could be turned back into a date. {L"en", L"1999-33", L"YYYY-J", CFX_DateTime(1999, 1, 1, 0, 0, 0, 0)}, {L"en", L"1999-033", L"YYYY-JJJ", CFX_DateTime(1999, 1, 1, 0, 0, 0, 0)}, {L"de_CH", L"30. Oktober 2004", L"D. MMMM YYYY", CFX_DateTime(2004, 10, 30, 0, 0, 0, 0)}, {L"fr_CA", L"30 octobre 2004", L"D MMMM YYYY", CFX_DateTime(2004, 10, 30, 0, 0, 0, 0)}, {L"en", L"Saturday, the 1 of January, 2000", L"EEEE, 'the' D 'of' MMMM, YYYY", CFX_DateTime(2000, 1, 1, 0, 0, 0, 0)}, {L"en", L"Sat, the 1 of January, 2000", L"EEE, 'the' D 'of' MMMM, YYYY", CFX_DateTime(2000, 1, 1, 0, 0, 0, 0)}, {L"en", L"7, the 1 of January, 2000", // 7 == Saturday as 1 == Sunday L"E, 'the' D 'of' MMMM, YYYY", CFX_DateTime(2000, 1, 1, 0, 0, 0, 0)}, {L"en", L"6, the 1 of January, 2000", // 6 == Saturday as 1 == Monday L"e, 'the' D 'of' MMMM, YYYY", CFX_DateTime(2000, 1, 1, 0, 0, 0, 0)}, {L"en", L"2004-07-22 Week of the month is 3", L"YYYY-MM-DD 'Week of the month is' w", CFX_DateTime(2004, 7, 22, 0, 0, 0, 0)}, {L"en", L"2004-07-22 Week of the year is 03", L"YYYY-MM-DD 'Week of the year is' WW", CFX_DateTime(2004, 7, 22, 0, 0, 0, 0)} // {L"ja", L"H15/11/3", L"gY/M/D", CFX_DateTime(2003, 11, 3, 0, 0, 0, 0)}, // {L"ja", L"\u5e731-1-8", L"ggY-M-D", CFX_DateTime(1989, 1, 8, 0, 0, 0, // 0)}, {L"ja", L"\u5e73\u621089/11/03", L"gggYY/MM/DD", // CFX_DateTime(1989, 11, 3, 0, 0, 0, 0)}, // {L"ja", L"u337b99/01/08", L"\u0067\u0067YY/MM/DD", // CFX_DateTime(1999, 1, 8, 0, 0, 0, 0)} }; // Note, none of the full width date symbols are listed here as they are // not supported. In theory there are the full width versions of DDD, // DDDD, MMM, MMMM, E, e, gg, YYY, YYYYY. for (size_t i = 0; i < FX_ArraySize(tests); ++i) { CFX_DateTime result; EXPECT_TRUE(fmt(tests[i].locale) ->ParseDateTime(tests[i].input, tests[i].pattern, FX_DATETIMETYPE_Date, &result)); EXPECT_EQ(tests[i].output, result) << " TEST: " << i; } }
TEST(SimpleParserTest, FindTagParamFromStart) { struct FindTagTestStruct { const unsigned char* input; unsigned int input_size; const char* token; int num_params; bool result; unsigned int result_pos; } test_data[] = { // Empty strings. STR_IN_TEST_CASE("", "Tj", 1, false, 0), STR_IN_TEST_CASE("", "", 1, false, 0), // Empty token. STR_IN_TEST_CASE(" T j", "", 1, false, 5), // No parameter. STR_IN_TEST_CASE("Tj", "Tj", 1, false, 2), STR_IN_TEST_CASE("(Tj", "Tj", 1, false, 3), // Partial token match. STR_IN_TEST_CASE("\r12\t34 56 78Tj", "Tj", 1, false, 15), // Regular cases with various parameters. STR_IN_TEST_CASE("\r\0abd Tj", "Tj", 1, true, 0), STR_IN_TEST_CASE("12 4 Tj 3 46 Tj", "Tj", 1, true, 2), STR_IN_TEST_CASE("er^ 2 (34) (5667) Tj", "Tj", 2, true, 5), STR_IN_TEST_CASE("<344> (232)\t343.4\n12 45 Tj", "Tj", 3, true, 11), STR_IN_TEST_CASE("1 2 3 4 5 6 7 8 cm", "cm", 6, true, 3), }; for (size_t i = 0; i < FX_ArraySize(test_data); ++i) { const FindTagTestStruct& data = test_data[i]; CPDF_SimpleParser parser(data.input, data.input_size); EXPECT_EQ(data.result, parser.FindTagParamFromStart(data.token, data.num_params)) << " for case " << i; EXPECT_EQ(data.result_pos, parser.GetCurPos()) << " for case " << i; } }
TEST_F(FPDFStructTreeEmbedderTest, GetType) { ASSERT_TRUE(OpenDocument("tagged_alt_text.pdf")); FPDF_PAGE page = LoadPage(0); ASSERT_TRUE(page); { ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page)); ASSERT_TRUE(struct_tree); ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get())); FPDF_STRUCTELEMENT element = FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0); ASSERT_NE(nullptr, element); unsigned short buffer[12]; memset(buffer, 0, sizeof(buffer)); // Deliberately pass in a small buffer size to make sure |buffer| remains // untouched. ASSERT_EQ(18U, FPDF_StructElement_GetType(element, buffer, 1)); for (size_t i = 0; i < FX_ArraySize(buffer); ++i) EXPECT_EQ(0U, buffer[i]); ASSERT_EQ(18U, FPDF_StructElement_GetType(element, buffer, sizeof(buffer))); const wchar_t kExpected[] = L"Document"; EXPECT_EQ(WideString(kExpected), WideString::FromUTF16LE(buffer, FXSYS_len(kExpected))); } UnloadPage(page); }
std::unique_ptr<CPDF_Object> CPDF_FontEncoding::Realize( WeakPtr<ByteStringPool> pPool) { int predefined = 0; for (int cs = PDFFONT_ENCODING_WINANSI; cs < PDFFONT_ENCODING_ZAPFDINGBATS; cs++) { const uint16_t* pSrc = PDF_UnicodesForPredefinedCharSet(cs); bool match = true; for (size_t i = 0; i < FX_ArraySize(m_Unicodes); i++) { if (m_Unicodes[i] != pSrc[i]) { match = false; break; } } if (match) { predefined = cs; break; } } if (predefined) { const char* pName; if (predefined == PDFFONT_ENCODING_WINANSI) pName = "WinAnsiEncoding"; else if (predefined == PDFFONT_ENCODING_MACROMAN) pName = "MacRomanEncoding"; else if (predefined == PDFFONT_ENCODING_MACEXPERT) pName = "MacExpertEncoding"; else return nullptr; return pdfium::MakeUnique<CPDF_Name>(pPool, pName); } const uint16_t* pStandard = PDF_UnicodesForPredefinedCharSet(PDFFONT_ENCODING_WINANSI); auto pDiff = pdfium::MakeUnique<CPDF_Array>(); for (size_t i = 0; i < FX_ArraySize(m_Unicodes); i++) { if (pStandard[i] == m_Unicodes[i]) continue; pDiff->AddNew<CPDF_Number>(static_cast<int>(i)); pDiff->AddNew<CPDF_Name>(PDF_AdobeNameFromUnicode(m_Unicodes[i])); } auto pDict = pdfium::MakeUnique<CPDF_Dictionary>(pPool); pDict->SetNewFor<CPDF_Name>("BaseEncoding", "WinAnsiEncoding"); pDict->SetFor("Differences", std::move(pDiff)); return std::move(pDict); }
void PDF_ReplaceAbbr(CPDF_Object* pObj) { switch (pObj->GetType()) { case PDFOBJ_DICTIONARY: { CPDF_Dictionary* pDict = pObj->AsDictionary(); for (const auto& it : *pDict) { CFX_ByteString key = it.first; CPDF_Object* value = it.second; CFX_ByteStringC fullname = PDF_FindFullName( PDF_InlineKeyAbbr, FX_ArraySize(PDF_InlineKeyAbbr), key); if (!fullname.IsEmpty()) { pDict->ReplaceKey(key, fullname); key = fullname; } if (value->IsName()) { CFX_ByteString name = value->GetString(); fullname = PDF_FindFullName(PDF_InlineValueAbbr, FX_ArraySize(PDF_InlineValueAbbr), name); if (!fullname.IsEmpty()) { pDict->SetAtName(key, fullname); } } else { PDF_ReplaceAbbr(value); } } break; } case PDFOBJ_ARRAY: { CPDF_Array* pArray = pObj->AsArray(); for (FX_DWORD i = 0; i < pArray->GetCount(); i++) { CPDF_Object* pElement = pArray->GetElement(i); if (pElement->IsName()) { CFX_ByteString name = pElement->GetString(); CFX_ByteStringC fullname = PDF_FindFullName( PDF_InlineValueAbbr, FX_ArraySize(PDF_InlineValueAbbr), name); if (!fullname.IsEmpty()) { pArray->SetAt(i, new CPDF_Name(fullname)); } } else { PDF_ReplaceAbbr(pElement); } } break; } } }
void CPDF_ModuleMgr::LoadEmbeddedKorea1CMaps() { CPDF_FontGlobals* pFontGlobals = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); pFontGlobals->m_EmbeddedCharsets[CIDSET_KOREA1].m_pMapList = g_FXCMAP_Korea1_cmaps; pFontGlobals->m_EmbeddedCharsets[CIDSET_KOREA1].m_Count = FX_ArraySize(g_FXCMAP_Korea1_cmaps); pFontGlobals->m_EmbeddedToUnicodes[CIDSET_KOREA1].m_pMap = g_FXCMAP_Korea1CID2Unicode_2; pFontGlobals->m_EmbeddedToUnicodes[CIDSET_KOREA1].m_Count = 18352; }
FX_BOOL CPWL_FontMap::IsStandardFont(const CFX_ByteString& sFontName) { for (size_t i = 0; i < FX_ArraySize(g_sDEStandardFontName); ++i) { if (sFontName == g_sDEStandardFontName[i]) return TRUE; } return FALSE; }
CPDF_CIDFont::CPDF_CIDFont() : m_pCID2UnicodeMap(nullptr), m_bCIDIsGID(false), m_bAnsiWidthsFixed(false), m_bAdobeCourierStd(false) { for (size_t i = 0; i < FX_ArraySize(m_CharBBox); ++i) m_CharBBox[i] = FX_RECT(-1, -1, -1, -1); }
CPDF_FontEncoding::CPDF_FontEncoding(int PredefinedEncoding) { const uint16_t* pSrc = PDF_UnicodesForPredefinedCharSet(PredefinedEncoding); if (!pSrc) { memset(m_Unicodes, 0, sizeof(m_Unicodes)); } else { for (size_t i = 0; i < FX_ArraySize(m_Unicodes); i++) m_Unicodes[i] = pSrc[i]; } }
wchar_t FX_GetArabicFromShaddaTable(wchar_t shadda) { static const size_t s_iShaddaCount = FX_ArraySize(gs_FX_ShaddaTable); for (size_t iStart = 0; iStart < s_iShaddaCount; iStart++) { const FX_ARASHADDA& v = gs_FX_ShaddaTable[iStart]; if (v.wShadda == shadda) return v.wIsolated; } return shadda; }
CFX_FontMapper::~CFX_FontMapper() { for (size_t i = 0; i < FX_ArraySize(m_FoxitFaces); ++i) { if (m_FoxitFaces[i]) FXFT_Done_Face(m_FoxitFaces[i]); } if (m_MMFaces[0]) FXFT_Done_Face(m_MMFaces[0]); if (m_MMFaces[1]) FXFT_Done_Face(m_MMFaces[1]); }
void CPDF_ModuleMgr::LoadEmbeddedGB1CMaps() { CPDF_FontGlobals* pFontGlobals = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); pFontGlobals->m_EmbeddedCharsets[CIDSET_GB1].m_pMapList = g_FXCMAP_GB1_cmaps; pFontGlobals->m_EmbeddedCharsets[CIDSET_GB1].m_Count = FX_ArraySize(g_FXCMAP_GB1_cmaps); pFontGlobals->m_EmbeddedToUnicodes[CIDSET_GB1].m_pMap = g_FXCMAP_GB1CID2Unicode_5; pFontGlobals->m_EmbeddedToUnicodes[CIDSET_GB1].m_Count = 30284; }
int PDF_GetStandardFontName(CFX_ByteString* name) { AltFontName* found = static_cast<AltFontName*>( FXSYS_bsearch(name->c_str(), g_AltFontNames, FX_ArraySize(g_AltFontNames), sizeof(AltFontName), CompareString)); if (!found) return -1; *name = g_Base14FontNames[found->m_Index]; return found->m_Index; }
int CPDF_Type3Font::GetCharWidthF(uint32_t charcode, int level) { if (charcode >= FX_ArraySize(m_CharWidthL)) charcode = 0; if (m_CharWidthL[charcode]) return m_CharWidthL[charcode]; const CPDF_Type3Char* pChar = LoadChar(charcode, level); return pChar ? pChar->m_Width : 0; }
void CBC_PDF417HighLevelEncoder::Inverse() { for (size_t l = 0; l < FX_ArraySize(MIXED); ++l) MIXED[l] = -1; for (uint8_t i = 0; i < FX_ArraySize(TEXT_MIXED_RAW); ++i) { uint8_t b = TEXT_MIXED_RAW[i]; if (b != 0) MIXED[b] = i; } for (size_t l = 0; l < FX_ArraySize(PUNCTUATION); ++l) PUNCTUATION[l] = -1; for (uint8_t i = 0; i < FX_ArraySize(TEXT_PUNCTUATION_RAW); ++i) { uint8_t b = TEXT_PUNCTUATION_RAW[i]; if (b != 0) PUNCTUATION[b] = i; } }
TEST(CPDF_LinkExtractTest, CheckMailLink) { CPDF_TestLinkExtract extractor; // Check cases that fail to extract valid mail link. const wchar_t* const invalid_strs[] = { L"", L"peter.pan", // '@' is required. L"abc@server", // Domain name needs at least one '.'. L"*****@*****.**", // '.' can not immediately precede '@'. L"abc@xyz&q.org", // Domain name should not contain '&'. L"*****@*****.**", // Domain name should not start with '.'. L"*****@*****.**" // Domain name should not have consecutive '.' }; for (size_t i = 0; i < FX_ArraySize(invalid_strs); ++i) { const wchar_t* const input = invalid_strs[i]; WideString text_str(input); EXPECT_FALSE(extractor.CheckMailLink(&text_str)) << input; } // Check cases that can extract valid mail link. // An array of {input_string, expected_extracted_email_address}. const wchar_t* const valid_strs[][2] = { {L"[email protected]", L"[email protected]"}, {L"*****@*****.**", L"*****@*****.**"}, {L"*****@*****.**", L"*****@*****.**"}, // '_' is ok before '@'. {L"*****@*****.**", L"*****@*****.**"}, // '-' is ok in user name. {L"*****@*****.**", L"*****@*****.**"}, // Stop at consecutive '.'. {L"*****@*****.**", L"*****@*****.**"}, // Remove heading '.'. {L"[email protected]?/", L"*****@*****.**"}, // Trim ending invalid chars. {L"fan{[email protected]", L"*****@*****.**"}, // Trim beginning invalid chars. {L"[email protected]..", L"*****@*****.**"}, // Trim the ending periods. {L"*****@*****.**", L"*****@*****.**"}, // Keep the original case. }; for (size_t i = 0; i < FX_ArraySize(valid_strs); ++i) { const wchar_t* const input = valid_strs[i][0]; WideString text_str(input); WideString expected_str(L"mailto:"); expected_str += valid_strs[i][1]; EXPECT_TRUE(extractor.CheckMailLink(&text_str)) << input; EXPECT_STREQ(expected_str.c_str(), text_str.c_str()); } }
const uint8_t* CPDF_CIDFont::GetCIDTransform(uint16_t CID) const { if (m_Charset != CIDSET_JAPAN1 || m_pFontFile) return nullptr; const auto* pEnd = g_Japan1_VertCIDs + FX_ArraySize(g_Japan1_VertCIDs); const auto* pTransform = std::lower_bound( g_Japan1_VertCIDs, pEnd, CID, [](const CIDTransform& entry, uint16_t cid) { return entry.cid < cid; }); return (pTransform < pEnd && CID == pTransform->cid) ? &pTransform->a : nullptr; }
CPDF_FormControl::HighlightingMode CPDF_FormControl::GetHighlightingMode() { if (!m_pWidgetDict) return Invert; CFX_ByteString csH = m_pWidgetDict->GetStringBy("H", "I"); for (size_t i = 0; i < FX_ArraySize(g_sHighlightingMode); ++i) { if (csH == g_sHighlightingMode[i]) return static_cast<HighlightingMode>(i); } return Invert; }
TEST_F(CFGAS_FormatStringTest, NullFormat) { struct { const wchar_t* locale; const wchar_t* pattern; const wchar_t* output; } tests[] = {{L"en", L"null{'n/a'}", L"n/a"}, {L"en", L"null{}", L""}}; for (size_t i = 0; i < FX_ArraySize(tests); ++i) { WideString result; EXPECT_TRUE(fmt(tests[i].locale)->FormatNull(tests[i].pattern, &result)); EXPECT_STREQ(tests[i].output, result.c_str()) << " TEST: " << i; } }
TEST_F(CFGAS_FormatStringTest, TimeFormat) { struct { const wchar_t* locale; const wchar_t* input; const wchar_t* pattern; const wchar_t* output; } tests[] = {{L"en", L"01:01:11", L"h:M A", L"1:1 AM"}, {L"en", L"13:01:11", L"h:M A", L"1:1 PM"}, {L"en", L"01:01:11", L"hh:MM:SS A", L"01:01:11 AM"}, {L"en", L"13:01:11", L"hh:MM:SS A", L"01:01:11 PM"}, {L"en", L"01:01:11", L"hh:MM:SS A Z", L"01:01:11 AM GMT-02:00"}, {L"en", L"01:01:11", L"hh:MM:SS A z", L"01:01:11 AM -02:00"}, // {L"en", L"01:01:11", L"hh:MM:SS A zz", L"01:01:11 AM GMT"}, // Should change ?*+ into ' ' when formatting. // {L"en", L"01:01:11", L"hh:MM:SS?*+A", L"01:01:11 AM"}, {L"en", L"12:01:01", L"k:MM:SS", L"12:01:01"}, {L"en", L"14:01:01", L"k:MM:SS", L"2:01:01"}, {L"en", L"12:01:11", L"kk:MM", L"12:01"}, {L"en", L"14:01:11", L"kk:MM", L"02:01"}, {L"en", L"12:01:11 +04:30", L"kk:MM", L"05:31"}, {L"en", L"12:01:11", L"kk:MM A", L"12:01 PM"}, {L"en", L"00:01:01", L"H:M:S", L"0:1:1"}, {L"en", L"13:02:11", L"H:M:S", L"13:2:11"}, {L"en", L"00:01:11.001", L"HH:M:S.FFF", L"00:1:11.001"}, {L"en", L"13:02:11", L"HH:M", L"13:2"}, {L"en", L"00:01:11", L"K:M", L"24:1"}, {L"en", L"00:02:11", L"KK:M", L"24:2"}, {L"en", L"11:11:11", L"HH:MM:SS 'o''clock' A Z", L"11:11:11 o'clock AM GMT-02:00"}, {L"en", L"14:30:59", L"h:MM A", L"2:30 PM"}, {L"en", L"14:30:59", L"HH:MM:SS A Z", L"14:30:59 PM GMT-02:00"}}; // Note, none of the full width time symbols are listed here // as they are not supported. In theory there are the full // width versions of kkk, kkkk, HHH, HHHH, KKK, KKKK, MMM, MMMM, // SSS, SSSS plus 2 more that the spec apparently forgot to // list the symbol. // The z modifier only appends if the TZ is outside of +0 SetTZ("UTC+2"); for (size_t i = 0; i < FX_ArraySize(tests); ++i) { WideString result; EXPECT_TRUE(fmt(tests[i].locale) ->FormatDateTime(tests[i].input, tests[i].pattern, FX_DATETIMETYPE_Time, &result)); EXPECT_STREQ(tests[i].output, result.c_str()) << " TEST: " << i; } SetTZ("UTC"); }
TEST(SimpleParserTest, GetWord) { static const pdfium::StrFuncTestData test_data[] = { // Empty src string. STR_IN_OUT_CASE("", ""), // Content with whitespaces only. STR_IN_OUT_CASE(" \t \0 \n", ""), // Content with comments only. STR_IN_OUT_CASE("%this is a test case\r\n%2nd line", ""), // Mixed whitespaces and comments. STR_IN_OUT_CASE(" \t \0%try()%haha\n %another line \aa", ""), // Name. STR_IN_OUT_CASE(" /Tester ", "/Tester"), // String. STR_IN_OUT_CASE("\t(nice day)!\n ", "(nice day)"), // String with nested braces. STR_IN_OUT_CASE("\t(It is a (long) day)!\n ", "(It is a (long) day)"), // String with escaped chars. STR_IN_OUT_CASE("\t(It is a \\(long\\) day!)hi\n ", "(It is a \\(long\\) day!)"), // Hex string. STR_IN_OUT_CASE(" \n<4545acdfedertt>abc ", "<4545acdfedertt>"), STR_IN_OUT_CASE(" \n<4545a<ed>ertt>abc ", "<4545a<ed>"), // Dictionary. STR_IN_OUT_CASE("<</oc 234 /color 2 3 R>>", "<<"), STR_IN_OUT_CASE("\t\t<< /abc>>", "<<"), // Handling ending delimiters. STR_IN_OUT_CASE("> little bear", ">"), STR_IN_OUT_CASE(") another bear", ")"), STR_IN_OUT_CASE(">> end ", ">>"), // No ending delimiters. STR_IN_OUT_CASE("(sdfgfgbcv", "(sdfgfgbcv"), // Regular cases. STR_IN_OUT_CASE("apple pear", "apple"), STR_IN_OUT_CASE(" pi=3.1415 ", "pi=3.1415"), STR_IN_OUT_CASE(" p t x c ", "p"), STR_IN_OUT_CASE(" pt\0xc ", "pt"), STR_IN_OUT_CASE(" $^&&*\t\0sdff ", "$^&&*"), STR_IN_OUT_CASE("\n\r+3.5656 -11.0", "+3.5656"), }; for (size_t i = 0; i < FX_ArraySize(test_data); ++i) { const pdfium::StrFuncTestData& data = test_data[i]; CPDF_SimpleParser parser(pdfium::make_span(data.input, data.input_size)); ByteStringView word = parser.GetWord(); EXPECT_EQ(data.expected_size, word.GetLength()) << " for case " << i; if (data.expected_size != word.GetLength()) continue; EXPECT_EQ( 0, memcmp(data.expected, word.unterminated_c_str(), data.expected_size)) << " for case " << i; } }
bool CXFA_FMCallExpression::IsBuildInFunc(CFX_WideTextBuf* funcName) { uint32_t uHash = FX_HashCode_GetW(funcName->AsStringC(), true); const XFA_FMBuildInFunc* pEnd = g_BuildInFuncs + FX_ArraySize(g_BuildInFuncs); const XFA_FMBuildInFunc* pFunc = std::lower_bound(g_BuildInFuncs, pEnd, uHash, [](const XFA_FMBuildInFunc& func, uint32_t hash) { return func.m_uHash < hash; }); if (pFunc < pEnd && uHash == pFunc->m_uHash) { funcName->Clear(); *funcName << pFunc->m_buildinfunc; return true; } return false; }
TEST(XfaUtilsImp, XFA_MapRotation) { struct TestCase { int input; int expected_output; } TestCases[] = {{-1000000, 80}, {-361, 359}, {-360, 0}, {-359, 1}, {-91, 269}, {-90, 270}, {-89, 271}, {-1, 359}, {0, 0}, {1, 1}, {89, 89}, {90, 90}, {91, 91}, {359, 359}, {360, 0}, {361, 1}, {100000, 280}}; for (size_t i = 0; i < FX_ArraySize(TestCases); ++i) { EXPECT_EQ(TestCases[i].expected_output, XFA_MapRotation(TestCases[i].input)); } }