summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrique Nakashima <hnakashima@chromium.org>2018-04-27 20:09:09 +0000
committerChromium commit bot <commit-bot@chromium.org>2018-04-27 20:09:09 +0000
commitf54ea0f44d53a6b1b3c4cb2c3a3285149510cccc (patch)
treeada091a76ee0b6c24294e085b67c10ca3f8cffa7
parent60ef3a231ba778d6a667068bdbb17f712eb335e4 (diff)
downloadpdfium-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.in73
-rw-r--r--testing/resources/xfa/xfa_multiline_textfield.pdf244
-rw-r--r--xfa/fwl/cfwl_edit.cpp2
-rw-r--r--xfa/fwl/cfwl_edit_embeddertest.cpp108
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);
+ }
}