diff options
author | Henrique Nakashima <hnakashima@chromium.org> | 2018-04-27 20:09:09 +0000 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2018-04-27 20:09:09 +0000 |
commit | f54ea0f44d53a6b1b3c4cb2c3a3285149510cccc (patch) | |
tree | ada091a76ee0b6c24294e085b67c10ca3f8cffa7 | |
parent | 60ef3a231ba778d6a667068bdbb17f712eb335e4 (diff) | |
download | pdfium-f54ea0f44d53a6b1b3c4cb2c3a3285149510cccc.tar.xz |
Fix backspace on 1st character of a line erases the line break.
Bug: chromium:836361
Change-Id: I39a0a3f9cb59ceb81f944dd5d0d4fd38a2e18a6b
Reviewed-on: https://pdfium-review.googlesource.com/31411
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
Commit-Queue: Henrique Nakashima <hnakashima@chromium.org>
-rw-r--r-- | testing/resources/xfa/xfa_multiline_textfield.in | 73 | ||||
-rw-r--r-- | testing/resources/xfa/xfa_multiline_textfield.pdf | 244 | ||||
-rw-r--r-- | xfa/fwl/cfwl_edit.cpp | 2 | ||||
-rw-r--r-- | xfa/fwl/cfwl_edit_embeddertest.cpp | 108 |
4 files changed, 422 insertions, 5 deletions
diff --git a/testing/resources/xfa/xfa_multiline_textfield.in b/testing/resources/xfa/xfa_multiline_textfield.in new file mode 100644 index 0000000000..215bc28015 --- /dev/null +++ b/testing/resources/xfa/xfa_multiline_textfield.in @@ -0,0 +1,73 @@ +{{header}} + +%% Original object ID: 24 0 +{{object 1 0}} +<< + /AcroForm 2 0 R + /Extensions << + /ADBE << + /BaseVersion /1.7 + /ExtensionLevel 8 + >> + >> + /NeedsRendering true + /Type /Catalog +>> +endobj + +%% Original object ID: 32 0 +{{object 2 0}} +<< + /XFA [ + (preamble) + 3 0 R + (config) + 4 0 R + (template) + 5 0 R + (localeSet) + 6 0 R + (postamble) + 7 0 R + ] +>> +endobj + +{{xfapreamble 3 0}} +{{xfaconfig 4 0}} + +{{object 5 0}} +<< + {{streamlen}} +>> +stream +<template xmlns="http://www.xfa.org/schema/xfa-template/3.3/"> + <subform name="form1" layout="tb" locale="en_US" restoreState="auto"> + <pageSet> + <pageArea name="Page1" id="Page1"> + <contentArea x="18pt" y="18pt" w="612pt" h="792pt"/> + <medium stock="default" short="612pt" long="792pt"/> + </pageArea> + </pageSet> + <subform w="576pt" h="756pt" name="Page1"> + <field name="TextField1" y="0pt" x="0pt" w="425pt" h="80pt"> + <ui> + <textEdit multiLine="1"> + <font typeface="Helvetica" size="16pt"/> + </textEdit> + </ui> + </field> + </subform> + </subform> +</template> +endstream +endobj + +{{xfalocale 6 0}} + +{{xfapostamble 7 0}} + +{{xref}} +{{trailer}} +{{startxref}} +%%EOF diff --git a/testing/resources/xfa/xfa_multiline_textfield.pdf b/testing/resources/xfa/xfa_multiline_textfield.pdf new file mode 100644 index 0000000000..f88af5bf9a --- /dev/null +++ b/testing/resources/xfa/xfa_multiline_textfield.pdf @@ -0,0 +1,244 @@ +%PDF-1.7 +% ò¤ô + +%% Original object ID: 24 0 +1 0 obj +<< + /AcroForm 2 0 R + /Extensions << + /ADBE << + /BaseVersion /1.7 + /ExtensionLevel 8 + >> + >> + /NeedsRendering true + /Type /Catalog +>> +endobj + +%% Original object ID: 32 0 +2 0 obj +<< + /XFA [ + (preamble) + 3 0 R + (config) + 4 0 R + (template) + 5 0 R + (localeSet) + 6 0 R + (postamble) + 7 0 R + ] +>> +endobj + +3 0 obj +<< + /Length 123 +>> +stream +<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/" timeStamp="2018-02-23T21:37:11Z" uuid="21482798-7bf0-40a4-bc5d-3cefdccf32b5"> +endstream +endobj +4 0 obj +<< + /Length 697 +>> +stream +<config xmlns="http://www.xfa.org/schema/xci/3.0/"> + <agent name="designer"> + <destination>pdf</destination> + <pdf> + <fontInfo/> + </pdf> + </agent> + <present> + <pdf> + <version>1.7</version> + <adobeExtensionLevel>8</adobeExtensionLevel> + <renderPolicy>client</renderPolicy> + <scriptModel>XFA</scriptModel> + <interactive>1</interactive> + </pdf> + <xdp> + <packets>*</packets> + </xdp> + <destination>pdf</destination> + <script> + <runScripts>server</runScripts> + </script> + </present> + <acrobat> + <acrobat7> + <dynamicRender>required</dynamicRender> + </acrobat7> + <validate>preSubmit</validate> + </acrobat> +</config> +endstream +endobj + +5 0 obj +<< + /Length 651 +>> +stream +<template xmlns="http://www.xfa.org/schema/xfa-template/3.3/"> + <subform name="form1" layout="tb" locale="en_US" restoreState="auto"> + <pageSet> + <pageArea name="Page1" id="Page1"> + <contentArea x="18pt" y="18pt" w="612pt" h="792pt"/> + <medium stock="default" short="612pt" long="792pt"/> + </pageArea> + </pageSet> + <subform w="576pt" h="756pt" name="Page1"> + <field name="TextField1" y="0pt" x="0pt" w="425pt" h="80pt"> + <ui> + <textEdit multiLine="1"> + <font typeface="Helvetica" size="16pt"/> + </textEdit> + </ui> + </field> + </subform> + </subform> +</template> +endstream +endobj + +6 0 obj +<< + /Length 3454 +>> +stream +<localeSet xmlns="http://www.xfa.org/schema/xfa-locale-set/2.7/"> + <locale name="en_US" desc="English (United States)"> + <calendarSymbols name="gregorian"> + <monthNames> + <month>January</month> + <month>February</month> + <month>March</month> + <month>April</month> + <month>May</month> + <month>June</month> + <month>July</month> + <month>August</month> + <month>September</month> + <month>October</month> + <month>November</month> + <month>December</month> + </monthNames> + <monthNames abbr="1"> + <month>Jan</month> + <month>Feb</month> + <month>Mar</month> + <month>Apr</month> + <month>May</month> + <month>Jun</month> + <month>Jul</month> + <month>Aug</month> + <month>Sep</month> + <month>Oct</month> + <month>Nov</month> + <month>Dec</month> + </monthNames> + <dayNames> + <day>Sunday</day> + <day>Monday</day> + <day>Tuesday</day> + <day>Wednesday</day> + <day>Thursday</day> + <day>Friday</day> + <day>Saturday</day> + </dayNames> + <dayNames abbr="1"> + <day>Sun</day> + <day>Mon</day> + <day>Tue</day> + <day>Wed</day> + <day>Thu</day> + <day>Fri</day> + <day>Sat</day> + </dayNames> + <meridiemNames> + <meridiem>AM</meridiem> + <meridiem>PM</meridiem> + </meridiemNames> + <eraNames> + <era>BC</era> + <era>AD</era> + </eraNames> + </calendarSymbols> + <datePatterns> + <datePattern name="full">EEEE, MMMM D, YYYY</datePattern> + <datePattern name="long">MMMM D, YYYY</datePattern> + <datePattern name="med">MMM D, YYYY</datePattern> + <datePattern name="short">M/D/YY</datePattern> + </datePatterns> + <timePatterns> + <timePattern name="full">h:MM:SS A Z</timePattern> + <timePattern name="long">h:MM:SS A Z</timePattern> + <timePattern name="med">h:MM:SS A</timePattern> + <timePattern name="short">h:MM A</timePattern> + </timePatterns> + <dateTimeSymbols>GyMdkHmsSEDFwWahKzZ</dateTimeSymbols> + <numberPatterns> + <numberPattern name="numeric">z,zz9.zzz</numberPattern> + <numberPattern name="currency">$z,zz9.99|($z,zz9.99)</numberPattern> + <numberPattern name="percent">z,zz9%</numberPattern> + </numberPatterns> + <numberSymbols> + <numberSymbol name="decimal">.</numberSymbol> + <numberSymbol name="grouping">,</numberSymbol> + <numberSymbol name="percent">%</numberSymbol> + <numberSymbol name="minus">-</numberSymbol> + <numberSymbol name="zero">0</numberSymbol> + </numberSymbols> + <currencySymbols> + <currencySymbol name="symbol">$</currencySymbol> + <currencySymbol name="isoname">USD</currencySymbol> + <currencySymbol name="decimal">.</currencySymbol> + </currencySymbols> + <typefaces> + <typeface name="Myriad Pro"/> + <typeface name="Minion Pro"/> + <typeface name="Courier Std"/> + <typeface name="Adobe Pi Std"/> + <typeface name="Adobe Hebrew"/> + <typeface name="Adobe Arabic"/> + <typeface name="Adobe Thai"/> + <typeface name="Kozuka Gothic Pro-VI M"/> + <typeface name="Kozuka Mincho Pro-VI R"/> + <typeface name="Adobe Ming Std L"/> + <typeface name="Adobe Song Std L"/> + <typeface name="Adobe Myungjo Std M"/> + </typefaces> + </locale> +</localeSet> +endstream +endobj + +7 0 obj +<< + /Length 10 +>> +stream +</xdp:xdp> +endstream +endobj + +xref +0 8 +0000000000 65535 f +0000000044 00000 n +0000000242 00000 n +0000000402 00000 n +0000000578 00000 n +0000001329 00000 n +0000002033 00000 n +0000005542 00000 n +trailer<< /Root 1 0 R /Size 8 >> +startxref +5605 +%%EOF diff --git a/xfa/fwl/cfwl_edit.cpp b/xfa/fwl/cfwl_edit.cpp index afa9aac87d..8ebc155a80 100644 --- a/xfa/fwl/cfwl_edit.cpp +++ b/xfa/fwl/cfwl_edit.cpp @@ -1252,7 +1252,7 @@ void CFWL_Edit::OnChar(CFWL_MessageKey* pMsg) { switch (c) { case L'\b': if (m_CursorPosition > 0) { - SetCursorPosition(m_EdtEngine.GetIndexBefore(m_CursorPosition)); + SetCursorPosition(m_CursorPosition - 1); m_EdtEngine.Delete(m_CursorPosition, 1); } break; diff --git a/xfa/fwl/cfwl_edit_embeddertest.cpp b/xfa/fwl/cfwl_edit_embeddertest.cpp index 7415e05845..ecc3b5ed13 100644 --- a/xfa/fwl/cfwl_edit_embeddertest.cpp +++ b/xfa/fwl/cfwl_edit_embeddertest.cpp @@ -8,13 +8,13 @@ #include "testing/embedder_test.h" #include "testing/embedder_test_timer_handling_delegate.h" #include "testing/gtest/include/gtest/gtest.h" +#include "testing/xfa_js_embedder_test.h" -class CFWLEditEmbeddertest : public EmbedderTest { +class CFWLEditEmbeddertest : public XFAJSEmbedderTest { protected: void SetUp() override { EmbedderTest::SetUp(); SetDelegate(&delegate_); - CreateAndInitializeFormPDF(); } void TearDown() override { @@ -22,8 +22,8 @@ class CFWLEditEmbeddertest : public EmbedderTest { EmbedderTest::TearDown(); } - void CreateAndInitializeFormPDF() { - EXPECT_TRUE(OpenDocument("xfa/email_recommended.pdf")); + void CreateAndInitializeFormPDF(const char* filename) { + EXPECT_TRUE(OpenDocument(filename)); page_ = LoadPage(0); ASSERT_TRUE(page_); } @@ -37,10 +37,12 @@ class CFWLEditEmbeddertest : public EmbedderTest { }; TEST_F(CFWLEditEmbeddertest, Trivial) { + CreateAndInitializeFormPDF("xfa/email_recommended.pdf"); ASSERT_EQ(0u, delegate().GetAlerts().size()); } TEST_F(CFWLEditEmbeddertest, LeftClickMouseSelection) { + CreateAndInitializeFormPDF("xfa/email_recommended.pdf"); FORM_OnLButtonDown(form_handle(), page(), 0, 115, 58); for (size_t i = 0; i < 10; ++i) FORM_OnChar(form_handle(), page(), 'a' + i, 0); @@ -58,6 +60,7 @@ TEST_F(CFWLEditEmbeddertest, LeftClickMouseSelection) { } TEST_F(CFWLEditEmbeddertest, DragMouseSelection) { + CreateAndInitializeFormPDF("xfa/email_recommended.pdf"); FORM_OnLButtonDown(form_handle(), page(), 0, 115, 58); for (size_t i = 0; i < 10; ++i) FORM_OnChar(form_handle(), page(), 'a' + i, 0); @@ -72,4 +75,101 @@ TEST_F(CFWLEditEmbeddertest, DragMouseSelection) { unsigned short buf[128]; unsigned long len = FORM_GetSelectedText(form_handle(), page(), &buf, 128); EXPECT_STREQ(L"defgh", WideString::FromUTF16LE(buf, len).c_str()); + + // TODO(hnakashima): This is incorrect. Visually 'abcdefgh' are selected. + const char kDraggedMD5[] = "69c13fe53b5fc422ebeab56d101a4658"; + { + ScopedFPDFBitmap page_bitmap = + RenderPageWithFlags(page(), form_handle(), FPDF_ANNOT); + CompareBitmap(page_bitmap.get(), 612, 792, kDraggedMD5); + } +} + +TEST_F(CFWLEditEmbeddertest, SimpleFill) { + CreateAndInitializeFormPDF("xfa/email_recommended.pdf"); + const char kBlankMD5[] = "eea5c72701270ac4a7edcc4df66d812a"; + { + ScopedFPDFBitmap page_bitmap = + RenderPageWithFlags(page(), form_handle(), FPDF_ANNOT); + CompareBitmap(page_bitmap.get(), 612, 792, kBlankMD5); + } + + FORM_OnLButtonDown(form_handle(), page(), 0, 115, 58); + for (size_t i = 0; i < 10; ++i) + FORM_OnChar(form_handle(), page(), 'a' + i, 0); + + const char kFilledMD5[] = "e73263fcea46c18d874b3d5a79f53805"; + { + ScopedFPDFBitmap page_bitmap = + RenderPageWithFlags(page(), form_handle(), FPDF_ANNOT); + CompareBitmap(page_bitmap.get(), 612, 792, kFilledMD5); + } +} + +TEST_F(CFWLEditEmbeddertest, FillWithNewLineWithoutMultiline) { + CreateAndInitializeFormPDF("xfa/email_recommended.pdf"); + FORM_OnLButtonDown(form_handle(), page(), 0, 115, 58); + for (size_t i = 0; i < 5; ++i) + FORM_OnChar(form_handle(), page(), 'a' + i, 0); + FORM_OnChar(form_handle(), page(), '\r', 0); + for (size_t i = 5; i < 10; ++i) + FORM_OnChar(form_handle(), page(), 'a' + i, 0); + + const char kFilledMD5[] = "e73263fcea46c18d874b3d5a79f53805"; + { + ScopedFPDFBitmap page_bitmap = + RenderPageWithFlags(page(), form_handle(), FPDF_ANNOT); + CompareBitmap(page_bitmap.get(), 612, 792, kFilledMD5); + } +} + +// Disabled due to flakiness. +TEST_F(CFWLEditEmbeddertest, DISABLED_FillWithNewLineWithMultiline) { + CreateAndInitializeFormPDF("xfa/xfa_multiline_textfield.pdf"); + FORM_OnLButtonDown(form_handle(), page(), 0, 115, 58); + + for (size_t i = 0; i < 5; ++i) + FORM_OnChar(form_handle(), page(), 'a' + i, 0); + FORM_OnChar(form_handle(), page(), '\r', 0); + for (size_t i = 5; i < 10; ++i) + FORM_OnChar(form_handle(), page(), 'a' + i, 0); + + // Should look like: + // abcde + // fghij| + { +#if _FX_PLATFORM_ == _FX_PLATFORM_LINUX_ + const char kFilledMultilineMD5[] = "fc1f4d5fdb2c5755005fc525b0a60ec9"; +#else + const char kFilledMultilineMD5[] = "a5654e027d8b1667c20f3b86d1918003"; +#endif // _FX_PLATFORM_ == _FX_PLATFORM_LINUX_ + ScopedFPDFBitmap page_bitmap = + RenderPageWithFlags(page(), form_handle(), FPDF_ANNOT); + CompareBitmap(page_bitmap.get(), 612, 792, kFilledMultilineMD5); + } + + for (size_t i = 0; i < 4; ++i) + FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Left, 0); + + // Should look like: + // abcde + // f|ghij + + // Two backspaces is a workaround because left arrow does not behave well + // in the first character of a line. It skips back to the previous line. + for (size_t i = 0; i < 2; ++i) + FORM_OnChar(form_handle(), page(), '\b', 0); + + // Should look like: + // abcde|ghij + { +#if _FX_PLATFORM_ == _FX_PLATFORM_LINUX_ + const char kMultilineBackspaceMD5[] = "8bb62a8100ff1e1cc113d4033e0d824e"; +#else + const char kMultilineBackspaceMD5[] = "a2f1dcab92bb1fb7c2f9ccc70100c989"; +#endif // _FX_PLATFORM_ == _FX_PLATFORM_LINUX_ + ScopedFPDFBitmap page_bitmap = + RenderPageWithFlags(page(), form_handle(), FPDF_ANNOT); + CompareBitmap(page_bitmap.get(), 612, 792, kMultilineBackspaceMD5); + } } |