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 <vmik...@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 <vmik...@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(); +} + } }
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits