[Libreoffice-commits] core.git: 2 commits - filter/inc filter/source sw/qa sw/source

Miklos Vajna vmiklos at suse.cz
Tue Feb 26 09:06:52 PST 2013


 filter/inc/filter/msfilter/rtfutil.hxx   |   23 +++++++++++++--
 filter/source/msfilter/rtfutil.cxx       |   47 +++++++++++++++++++++++++++----
 sw/qa/extras/rtfexport/data/fdo61507.rtf |   12 +++++++
 sw/qa/extras/rtfexport/rtfexport.cxx     |   19 ++++++++++++
 sw/source/filter/ww8/rtfexport.cxx       |   15 ++++++---
 sw/source/filter/ww8/rtfexport.hxx       |    2 -
 6 files changed, 104 insertions(+), 14 deletions(-)

New commits:
commit 5de52551a963b932cc23c2ea75f709fa1924520b
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Tue Feb 26 17:28:27 2013 +0100

    fdo#61507 export of RTF_TITLE may need RTF_UPR and RTF_UD
    
    Change-Id: I3b8fe209a96e5119541e09cb5dbda8a2c6926b40

diff --git a/sw/qa/extras/rtfexport/data/fdo61507.rtf b/sw/qa/extras/rtfexport/data/fdo61507.rtf
new file mode 100644
index 0000000..1fe8654
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/fdo61507.rtf
@@ -0,0 +1,12 @@
+{\rtf1
+{\info
+{\upr
+{\title \'c9\'c1???}
+{\*\ud\uc0
+{\title \'c9\'c1
+{\uc1\u336 O\u368 U\u8749 ?}
+}
+}
+}
+}
+Hello.}
diff --git a/sw/qa/extras/rtfexport/rtfexport.cxx b/sw/qa/extras/rtfexport/rtfexport.cxx
index be9b27b..5294670 100644
--- a/sw/qa/extras/rtfexport/rtfexport.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport.cxx
@@ -69,6 +69,7 @@ public:
     void testTextFrames();
     void testFdo53604();
     void testFdo52286();
+    void testFdo61507();
 
     CPPUNIT_TEST_SUITE(Test);
 #if !defined(MACOSX) && !defined(WNT)
@@ -113,6 +114,7 @@ void Test::run()
         {"textframes.odt", &Test::testTextFrames},
         {"fdo53604.odt", &Test::testFdo53604},
         {"fdo52286.odt", &Test::testFdo52286},
+        {"fdo61507.rtf", &Test::testFdo61507},
     };
     // Don't test the first import of these, for some reason those tests fail
     const char* aBlacklist[] = {
@@ -463,6 +465,23 @@ void Test::testFdo52286()
     CPPUNIT_ASSERT_EQUAL(sal_Int32(58), getProperty<sal_Int32>(getRun(getParagraph(2), 2), "CharEscapementHeight"));
 }
 
+void Test::testFdo61507()
+{
+    /*
+     * Unicode-only characters in \title confused Wordpad. Once the exporter
+     * was fixed to guard the problematic characters with \upr and \ud, the
+     * importer didn't cope with these new keywords.
+     */
+
+    uno::Reference<document::XDocumentPropertiesSupplier> xDocumentPropertiesSupplier(mxComponent, uno::UNO_QUERY);
+    uno::Reference<document::XDocumentProperties> xDocumentProperties(xDocumentPropertiesSupplier->getDocumentProperties());
+    OUString aExpected = OUString("ÉÁŐŰ∭", 11, RTL_TEXTENCODING_UTF8);
+    CPPUNIT_ASSERT_EQUAL(aExpected, xDocumentProperties->getTitle());
+
+    // Only "Hello.", no additional characters.
+    CPPUNIT_ASSERT_EQUAL(6, getLength());
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/ww8/rtfexport.cxx b/sw/source/filter/ww8/rtfexport.cxx
index a2512059..34073be 100644
--- a/sw/source/filter/ww8/rtfexport.cxx
+++ b/sw/source/filter/ww8/rtfexport.cxx
@@ -395,7 +395,7 @@ void RtfExport::WriteInfo()
     }
 
     if (xDocProps.is()) {
-        OutUnicode(OOO_STRING_SVTOOLS_RTF_TITLE, xDocProps->getTitle());
+        OutUnicode(OOO_STRING_SVTOOLS_RTF_TITLE, xDocProps->getTitle(), true);
         OutUnicode(OOO_STRING_SVTOOLS_RTF_SUBJECT, xDocProps->getSubject());
 
         OutUnicode(OOO_STRING_SVTOOLS_RTF_KEYWORDS,
@@ -801,13 +801,18 @@ SvStream& RtfExport::OutLong( long nVal )
     return m_pWriter->OutLong( Strm(), nVal );
 }
 
-void RtfExport::OutUnicode(const sal_Char *pToken, const String &rContent)
+void RtfExport::OutUnicode(const sal_Char *pToken, const String &rContent, bool bUpr)
 {
     if (rContent.Len())
     {
-        Strm() << '{' << pToken << ' ';
-        Strm() << msfilter::rtfutil::OutString( rContent, eCurrentEncoding ).getStr();
-        Strm() << '}';
+        if (!bUpr)
+        {
+            Strm() << '{' << pToken << ' ';
+            Strm() << msfilter::rtfutil::OutString( rContent, eCurrentEncoding ).getStr();
+            Strm() << '}';
+        }
+        else
+            Strm() << msfilter::rtfutil::OutStringUpr(pToken, rContent, eCurrentEncoding).getStr();
     }
 }
 
diff --git a/sw/source/filter/ww8/rtfexport.hxx b/sw/source/filter/ww8/rtfexport.hxx
index 6cd33ce..8fc8e26 100644
--- a/sw/source/filter/ww8/rtfexport.hxx
+++ b/sw/source/filter/ww8/rtfexport.hxx
@@ -155,7 +155,7 @@ public:
     SvStream& Strm();
     SvStream& OutULong( sal_uLong nVal );
     SvStream& OutLong( long nVal );
-    void OutUnicode(const sal_Char *pToken, const String &rContent);
+    void OutUnicode(const sal_Char *pToken, const String &rContent, bool bUpr = false);
     void OutDateTime(const sal_Char* pStr, const util::DateTime& rDT );
     void OutPageDescription( const SwPageDesc& rPgDsc, bool bWriteReset, bool bCheckForFirstPage );
 
commit 3a934d928e455eca38f124072c20a624a64aa225
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Tue Feb 26 17:27:11 2013 +0100

    msfilter: support checking if conversion to legacy encoding is lossless or not
    
    Change-Id: I69405c5883af6d3b119b177f51229c8a78f8c24d

diff --git a/filter/inc/filter/msfilter/rtfutil.hxx b/filter/inc/filter/msfilter/rtfutil.hxx
index 6f5d82c..aa842fd 100644
--- a/filter/inc/filter/msfilter/rtfutil.hxx
+++ b/filter/inc/filter/msfilter/rtfutil.hxx
@@ -41,10 +41,27 @@ namespace rtfutil {
 MSFILTER_DLLPUBLIC OString OutHex(sal_uLong nHex, sal_uInt8 nLen);
 
 /// Handles correct unicode and legacy export of a single character.
-MSFILTER_DLLPUBLIC OString OutChar(sal_Unicode c, int *pUCMode, rtl_TextEncoding eDestEnc);
+MSFILTER_DLLPUBLIC OString OutChar(sal_Unicode c, int *pUCMode, rtl_TextEncoding eDestEnc, bool* pSuccess = 0, bool bUnicode = true);
 
-/// Handles correct unicode and legacy export of a string.
-MSFILTER_DLLPUBLIC OString OutString(const String &rStr, rtl_TextEncoding eDestEnc);
+/**
+ * Handles correct unicode and legacy export of a string.
+ *
+ * @param rStr the string to export
+ * @param eDestEnc the legacy encoding to use
+ * @param bUnicode if unicode output is wanted as well, or just legacy
+ */
+MSFILTER_DLLPUBLIC OString OutString(const String &rStr, rtl_TextEncoding eDestEnc, bool bUnicode = true);
+
+/**
+ * Handles correct unicode and legacy export of a string, when a
+ * '{' \upr '{' keyword ansi_text '}{\*' \ud '{' keyword Unicode_text '}}}'
+ * construct should be used.
+ *
+ * @param pToken the keyword
+ * @param rStr the text to export
+ * @param eDestEnc the legacy encoding to use
+ */
+MSFILTER_DLLPUBLIC OString OutStringUpr(const sal_Char *pToken, const String &rStr, rtl_TextEncoding eDestEnc);
 
 }
 }
diff --git a/filter/source/msfilter/rtfutil.cxx b/filter/source/msfilter/rtfutil.cxx
index ebb72bd..3e2dfb0 100644
--- a/filter/source/msfilter/rtfutil.cxx
+++ b/filter/source/msfilter/rtfutil.cxx
@@ -53,8 +53,10 @@ OString OutHex(sal_uLong nHex, sal_uInt8 nLen)
     return OString(pStr);
 }
 
-OString OutChar(sal_Unicode c, int *pUCMode, rtl_TextEncoding eDestEnc)
+OString OutChar(sal_Unicode c, int *pUCMode, rtl_TextEncoding eDestEnc, bool* pSuccess, bool bUnicode)
 {
+    if (pSuccess)
+        *pSuccess = true;
     OStringBuffer aBuf;
     const sal_Char* pStr = 0;
     // 0x0b instead of \n, etc because of the replacements in SwWW8AttrIter::GetSnippet()
@@ -91,10 +93,13 @@ OString OutChar(sal_Unicode c, int *pUCMode, rtl_TextEncoding eDestEnc)
             else {
                 OUString sBuf(&c, 1);
                 OString sConverted;
-                sBuf.convertToString(&sConverted, eDestEnc, OUSTRING_TO_OSTRING_CVTFLAGS);
+                if (pSuccess)
+                    *pSuccess &= sBuf.convertToString(&sConverted, eDestEnc, RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR);
+                else
+                    sBuf.convertToString(&sConverted, eDestEnc, OUSTRING_TO_OSTRING_CVTFLAGS);
                 const sal_Int32 nLen = sConverted.getLength();
 
-                if (pUCMode)
+                if (pUCMode && bUnicode)
                 {
                     if (*pUCMode != nLen)
                     {
@@ -130,13 +135,13 @@ OString OutChar(sal_Unicode c, int *pUCMode, rtl_TextEncoding eDestEnc)
     return aBuf.makeStringAndClear();
 }
 
-OString OutString(const String &rStr, rtl_TextEncoding eDestEnc)
+OString OutString(const String &rStr, rtl_TextEncoding eDestEnc, bool bUnicode)
 {
     SAL_INFO("filter.ms", OSL_THIS_FUNC << ", rStr = '" << OUString(rStr) << "'");
     OStringBuffer aBuf;
     int nUCMode = 1;
     for (xub_StrLen n = 0; n < rStr.Len(); ++n)
-        aBuf.append(OutChar(rStr.GetChar(n), &nUCMode, eDestEnc));
+        aBuf.append(OutChar(rStr.GetChar(n), &nUCMode, eDestEnc, 0, bUnicode));
     if (nUCMode != 1) {
         aBuf.append(OOO_STRING_SVTOOLS_RTF_UC);
         aBuf.append((sal_Int32)1);
@@ -145,6 +150,38 @@ OString OutString(const String &rStr, rtl_TextEncoding eDestEnc)
     return aBuf.makeStringAndClear();
 }
 
+/// Checks if lossless conversion of the string to eDestEnc is possible or not.
+static bool TryOutString(const String &rStr, rtl_TextEncoding eDestEnc)
+{
+    int nUCMode = 1;
+    for (xub_StrLen n = 0; n < rStr.Len(); ++n)
+    {
+        bool bRet;
+        OutChar(rStr.GetChar(n), &nUCMode, eDestEnc, &bRet);
+        if (!bRet)
+            return false;
+    }
+    return true;
+}
+
+OString OutStringUpr(const sal_Char *pToken, const String &rStr, rtl_TextEncoding eDestEnc)
+{
+    if (TryOutString(rStr, eDestEnc))
+        return OString("{") + pToken + " " + OutString(rStr, eDestEnc) + "}";
+
+    OStringBuffer aRet;
+    aRet.append("{" OOO_STRING_SVTOOLS_RTF_UPR "{");
+    aRet.append(pToken);
+    aRet.append(" ");
+    aRet.append(OutString(rStr, eDestEnc, /*bUnicode =*/ false));
+    aRet.append("}{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_UD "{");
+    aRet.append(pToken);
+    aRet.append(" ");
+    aRet.append(OutString(rStr, eDestEnc));
+    aRet.append("}}}");
+    return aRet.makeStringAndClear();
+}
+
 }
 }
 


More information about the Libreoffice-commits mailing list