Kaydet (Commit) fd95fb97 authored tarafından Serge Krot's avatar Serge Krot Kaydeden (comit) Thorsten Behrens

tdf#125719 sw: rtf: refactor associated character properties

1. \rtlch, \ltrch should be placed before their properties.
2. Do not mix associated and normal character properties in output.
3. Do not output empty "\rtlch \ltrch", "\ltrch \rtlch" pairs.
4. Handle associated character properties runs instead of
handling separately their parts without order of them.

Change-Id: Ibbf7365d04708682a5f1eb664a579c60a47465d2
Reviewed-on: https://gerrit.libreoffice.org/72578
Tested-by: Jenkins
Reviewed-by: 's avatarThorsten Behrens <Thorsten.Behrens@CIB.de>
üst 50696615
This diff is collapsed.
This diff is collapsed.
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <com/sun/star/text/XFootnote.hpp> #include <com/sun/star/text/XFootnote.hpp>
#include <com/sun/star/text/XFootnotesSupplier.hpp> #include <com/sun/star/text/XFootnotesSupplier.hpp>
#include <com/sun/star/text/TextContentAnchorType.hpp> #include <com/sun/star/text/TextContentAnchorType.hpp>
#include <com/sun/star/awt/FontWeight.hpp>
class Test : public SwModelTestBase class Test : public SwModelTestBase
{ {
...@@ -228,6 +229,24 @@ DECLARE_RTFEXPORT_TEST(testTdf122455, "tdf122455.rtf") ...@@ -228,6 +229,24 @@ DECLARE_RTFEXPORT_TEST(testTdf122455, "tdf122455.rtf")
CPPUNIT_ASSERT_EQUAL(16.0, getProperty<double>(getRun(getParagraph(1), 1), "CharHeight")); CPPUNIT_ASSERT_EQUAL(16.0, getProperty<double>(getRun(getParagraph(1), 1), "CharHeight"));
} }
DECLARE_RTFEXPORT_TEST(testTdf125719_case_1, "tdf125719_case_1.rtf")
{
CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL,
getProperty<float>(getRun(getParagraph(1), 1), "CharWeight"));
CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL,
getProperty<float>(getRun(getParagraph(3), 1), "CharWeight"));
}
DECLARE_RTFEXPORT_TEST(testTdf125719_case_2, "tdf125719_case_2.rtf")
{
CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD,
getProperty<float>(getRun(getParagraph(1), 1), "CharWeight"));
CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD,
getProperty<float>(getRun(getParagraph(3), 1), "CharWeight"));
CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL,
getProperty<float>(getRun(getParagraph(5), 1), "CharWeight"));
}
DECLARE_RTFEXPORT_TEST(testTabs, "tabs.rtf") DECLARE_RTFEXPORT_TEST(testTabs, "tabs.rtf")
{ {
// Test tab alignment in decimal mode. // Test tab alignment in decimal mode.
......
...@@ -84,7 +84,7 @@ public: ...@@ -84,7 +84,7 @@ public:
// Access to (anyway) private buffers, used by the sdr exporter // Access to (anyway) private buffers, used by the sdr exporter
OStringBuffer& RunText(); OStringBuffer& RunText();
OStringBuffer& Styles() { return m_aStyles; } OStringBuffer& Styles() { return m_aStyles; }
OStringBuffer& StylesEnd(); OString MoveCharacterProperties(bool aAutoWriteRtlLtr = false);
/// Output text (without markup). /// Output text (without markup).
void RawText(const OUString& rText, rtl_TextEncoding eCharSet) override; void RawText(const OUString& rText, rtl_TextEncoding eCharSet) override;
...@@ -516,9 +516,12 @@ private: ...@@ -516,9 +516,12 @@ private:
*/ */
OStringBuffer m_aStyles; OStringBuffer m_aStyles;
/* /*
* This is the same as m_aStyles but the contents of it is written last. * This is the same as m_aStyles but the contents of it is Assoc.
*/ */
OStringBuffer m_aStylesEnd; OStringBuffer m_aStylesAssoc;
bool m_bIsRTL;
sal_uInt16 m_nScript;
bool m_bControlLtrRtl;
sal_Int32 m_nNextAnnotationMarkId; sal_Int32 m_nNextAnnotationMarkId;
sal_Int32 m_nCurrentAnnotationMarkId; sal_Int32 m_nCurrentAnnotationMarkId;
......
...@@ -706,8 +706,7 @@ void RtfSdrExport::WriteOutliner(const OutlinerParaObject& rParaObj, TextTypes e ...@@ -706,8 +706,7 @@ void RtfSdrExport::WriteOutliner(const OutlinerParaObject& rParaObj, TextTypes e
const sal_Int32 nEnd = aStr.getLength(); const sal_Int32 nEnd = aStr.getLength();
aAttrIter.OutParaAttr(false); aAttrIter.OutParaAttr(false);
m_rAttrOutput.RunText().append(m_rAttrOutput.Styles().makeStringAndClear()); m_rAttrOutput.RunText().append(m_rAttrOutput.MoveCharacterProperties(true));
m_rAttrOutput.RunText().append(m_rAttrOutput.StylesEnd().makeStringAndClear());
do do
{ {
...@@ -716,8 +715,7 @@ void RtfSdrExport::WriteOutliner(const OutlinerParaObject& rParaObj, TextTypes e ...@@ -716,8 +715,7 @@ void RtfSdrExport::WriteOutliner(const OutlinerParaObject& rParaObj, TextTypes e
aAttrIter.OutAttr(nCurrentPos); aAttrIter.OutAttr(nCurrentPos);
m_rAttrOutput.RunText().append('{'); m_rAttrOutput.RunText().append('{');
m_rAttrOutput.RunText().append(m_rAttrOutput.Styles().makeStringAndClear()); m_rAttrOutput.RunText().append(m_rAttrOutput.MoveCharacterProperties(true));
m_rAttrOutput.RunText().append(m_rAttrOutput.StylesEnd().makeStringAndClear());
m_rAttrOutput.RunText().append(SAL_NEWLINE_STRING); m_rAttrOutput.RunText().append(SAL_NEWLINE_STRING);
bool bTextAtr = aAttrIter.IsTextAttr(nCurrentPos); bool bTextAtr = aAttrIter.IsTextAttr(nCurrentPos);
if (!bTextAtr) if (!bTextAtr)
......
...@@ -473,8 +473,7 @@ RTFError RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword) ...@@ -473,8 +473,7 @@ RTFError RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
m_aStates.top().setCurrentEncoding(getEncoding(getFontIndex(m_nDefaultFontIndex))); m_aStates.top().setCurrentEncoding(getEncoding(getFontIndex(m_nDefaultFontIndex)));
m_aStates.top().getCharacterAttributes() = getDefaultState().getCharacterAttributes(); m_aStates.top().getCharacterAttributes() = getDefaultState().getCharacterAttributes();
m_aStates.top().setCurrentCharacterStyleIndex(-1); m_aStates.top().setCurrentCharacterStyleIndex(-1);
m_aStates.top().setIsRightToLeft(false); m_aStates.top().setRunType(RTFParserState::RunType::NONE);
m_aStates.top().setRunType(RTFParserState::RunType::LOCH);
} }
break; break;
case RTF_PARD: case RTF_PARD:
...@@ -565,6 +564,7 @@ RTFError RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword) ...@@ -565,6 +564,7 @@ RTFError RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
case RTF_RTLSECT: case RTF_RTLSECT:
{ {
auto pValue = new RTFValue(nKeyword == RTF_LTRSECT ? 0 : 1); auto pValue = new RTFValue(nKeyword == RTF_LTRSECT ? 0 : 1);
m_aStates.top().setRunType(RTFParserState::RunType::NONE);
m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_EG_SectPrContents_textDirection, m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_EG_SectPrContents_textDirection,
pValue); pValue);
} }
...@@ -573,20 +573,29 @@ RTFError RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword) ...@@ -573,20 +573,29 @@ RTFError RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
case RTF_RTLPAR: case RTF_RTLPAR:
{ {
auto pValue = new RTFValue(nKeyword == RTF_LTRPAR ? 0 : 1); auto pValue = new RTFValue(nKeyword == RTF_LTRPAR ? 0 : 1);
m_aStates.top().setRunType(RTFParserState::RunType::NONE);
m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_bidi, pValue); m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_bidi, pValue);
} }
break; break;
case RTF_LTRROW: case RTF_LTRROW:
case RTF_RTLROW: case RTF_RTLROW:
m_aStates.top().setRunType(RTFParserState::RunType::NONE);
m_aStates.top().getTableRowSprms().set(NS_ooxml::LN_CT_TblPrBase_bidiVisual, m_aStates.top().getTableRowSprms().set(NS_ooxml::LN_CT_TblPrBase_bidiVisual,
new RTFValue(int(nKeyword == RTF_RTLROW))); new RTFValue(int(nKeyword == RTF_RTLROW)));
break; break;
case RTF_LTRCH: case RTF_LTRCH:
// dmapper does not support this. // dmapper does not support this.
m_aStates.top().setIsRightToLeft(false); if (m_aStates.top().getRunType() == RTFParserState::RunType::RTLCH_LTRCH_1)
m_aStates.top().setRunType(RTFParserState::RunType::RTLCH_LTRCH_2);
else
m_aStates.top().setRunType(RTFParserState::RunType::LTRCH_RTLCH_1);
break; break;
case RTF_RTLCH: case RTF_RTLCH:
m_aStates.top().setIsRightToLeft(true); if (m_aStates.top().getRunType() == RTFParserState::RunType::LTRCH_RTLCH_1)
m_aStates.top().setRunType(RTFParserState::RunType::LTRCH_RTLCH_2);
else
m_aStates.top().setRunType(RTFParserState::RunType::RTLCH_LTRCH_1);
if (m_aDefaultState.getCurrentEncoding() == RTL_TEXTENCODING_MS_1255) if (m_aDefaultState.getCurrentEncoding() == RTL_TEXTENCODING_MS_1255)
m_aStates.top().setCurrentEncoding(m_aDefaultState.getCurrentEncoding()); m_aStates.top().setCurrentEncoding(m_aDefaultState.getCurrentEncoding());
break; break;
......
...@@ -164,10 +164,22 @@ RTFError RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) ...@@ -164,10 +164,22 @@ RTFError RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
{ {
case RTF_FS: case RTF_FS:
case RTF_AFS: case RTF_AFS:
nSprm = (m_aStates.top().getIsRightToLeft() switch (m_aStates.top().getRunType())
|| m_aStates.top().getRunType() == RTFParserState::RunType::HICH) {
? NS_ooxml::LN_EG_RPrBase_szCs case RTFParserState::RunType::HICH:
: NS_ooxml::LN_EG_RPrBase_sz; case RTFParserState::RunType::RTLCH_LTRCH_1:
case RTFParserState::RunType::LTRCH_RTLCH_2:
case RTFParserState::RunType::DBCH:
nSprm = NS_ooxml::LN_EG_RPrBase_szCs;
break;
case RTFParserState::RunType::NONE:
case RTFParserState::RunType::LOCH:
case RTFParserState::RunType::LTRCH_RTLCH_1:
case RTFParserState::RunType::RTLCH_LTRCH_2:
default:
nSprm = NS_ooxml::LN_EG_RPrBase_sz;
break;
}
break; break;
case RTF_EXPNDTW: case RTF_EXPNDTW:
nSprm = NS_ooxml::LN_EG_RPrBase_spacing; nSprm = NS_ooxml::LN_EG_RPrBase_spacing;
...@@ -191,19 +203,23 @@ RTFError RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) ...@@ -191,19 +203,23 @@ RTFError RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
{ {
case RTF_LANG: case RTF_LANG:
case RTF_ALANG: case RTF_ALANG:
if (m_aStates.top().getIsRightToLeft() switch (m_aStates.top().getRunType())
|| m_aStates.top().getRunType() == RTFParserState::RunType::HICH)
{
nSprm = NS_ooxml::LN_CT_Language_bidi;
}
else if (m_aStates.top().getRunType() == RTFParserState::RunType::DBCH)
{ {
nSprm = NS_ooxml::LN_CT_Language_eastAsia; case RTFParserState::RunType::HICH:
} case RTFParserState::RunType::RTLCH_LTRCH_1:
else case RTFParserState::RunType::LTRCH_RTLCH_2:
{ nSprm = NS_ooxml::LN_CT_Language_bidi;
assert(m_aStates.top().getRunType() == RTFParserState::RunType::LOCH); break;
nSprm = NS_ooxml::LN_CT_Language_val; case RTFParserState::RunType::DBCH:
nSprm = NS_ooxml::LN_CT_Language_eastAsia;
break;
case RTFParserState::RunType::NONE:
case RTFParserState::RunType::LOCH:
case RTFParserState::RunType::LTRCH_RTLCH_1:
case RTFParserState::RunType::RTLCH_LTRCH_2:
default:
nSprm = NS_ooxml::LN_CT_Language_val;
break;
} }
break; break;
case RTF_LANGFE: // this one is always CJK apparently case RTF_LANGFE: // this one is always CJK apparently
...@@ -336,20 +352,25 @@ RTFError RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) ...@@ -336,20 +352,25 @@ RTFError RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
{ {
case RTF_F: case RTF_F:
case RTF_AF: case RTF_AF:
if (m_aStates.top().getIsRightToLeft() switch (m_aStates.top().getRunType())
|| m_aStates.top().getRunType() == RTFParserState::RunType::HICH)
{
nSprm = NS_ooxml::LN_CT_Fonts_cs;
}
else if (m_aStates.top().getRunType() == RTFParserState::RunType::DBCH)
{ {
nSprm = NS_ooxml::LN_CT_Fonts_eastAsia; case RTFParserState::RunType::HICH:
} case RTFParserState::RunType::RTLCH_LTRCH_1:
else case RTFParserState::RunType::LTRCH_RTLCH_2:
{ nSprm = NS_ooxml::LN_CT_Fonts_cs;
assert(m_aStates.top().getRunType() == RTFParserState::RunType::LOCH); break;
nSprm = NS_ooxml::LN_CT_Fonts_ascii; case RTFParserState::RunType::DBCH:
nSprm = NS_ooxml::LN_CT_Fonts_eastAsia;
break;
case RTFParserState::RunType::NONE:
case RTFParserState::RunType::LOCH:
case RTFParserState::RunType::LTRCH_RTLCH_1:
case RTFParserState::RunType::RTLCH_LTRCH_2:
default:
nSprm = NS_ooxml::LN_CT_Fonts_ascii;
break;
} }
if (m_aStates.top().getDestination() == Destination::FONTTABLE if (m_aStates.top().getDestination() == Destination::FONTTABLE
|| m_aStates.top().getDestination() == Destination::FONTENTRY) || m_aStates.top().getDestination() == Destination::FONTENTRY)
{ {
......
...@@ -1850,17 +1850,41 @@ RTFError RTFDocumentImpl::dispatchToggle(RTFKeyword nKeyword, bool bParam, int n ...@@ -1850,17 +1850,41 @@ RTFError RTFDocumentImpl::dispatchToggle(RTFKeyword nKeyword, bool bParam, int n
{ {
case RTF_B: case RTF_B:
case RTF_AB: case RTF_AB:
nSprm = (m_aStates.top().getIsRightToLeft() switch (m_aStates.top().getRunType())
|| m_aStates.top().getRunType() == RTFParserState::RunType::HICH) {
? NS_ooxml::LN_EG_RPrBase_bCs case RTFParserState::RunType::HICH:
: NS_ooxml::LN_EG_RPrBase_b; case RTFParserState::RunType::RTLCH_LTRCH_1:
case RTFParserState::RunType::LTRCH_RTLCH_2:
case RTFParserState::RunType::DBCH:
nSprm = NS_ooxml::LN_EG_RPrBase_bCs;
break;
case RTFParserState::RunType::NONE:
case RTFParserState::RunType::LOCH:
case RTFParserState::RunType::LTRCH_RTLCH_1:
case RTFParserState::RunType::RTLCH_LTRCH_2:
default:
nSprm = NS_ooxml::LN_EG_RPrBase_b;
break;
}
break; break;
case RTF_I: case RTF_I:
case RTF_AI: case RTF_AI:
nSprm = (m_aStates.top().getIsRightToLeft() switch (m_aStates.top().getRunType())
|| m_aStates.top().getRunType() == RTFParserState::RunType::HICH) {
? NS_ooxml::LN_EG_RPrBase_iCs case RTFParserState::RunType::HICH:
: NS_ooxml::LN_EG_RPrBase_i; case RTFParserState::RunType::RTLCH_LTRCH_1:
case RTFParserState::RunType::LTRCH_RTLCH_2:
case RTFParserState::RunType::DBCH:
nSprm = NS_ooxml::LN_EG_RPrBase_iCs;
break;
case RTFParserState::RunType::NONE:
case RTFParserState::RunType::LOCH:
case RTFParserState::RunType::LTRCH_RTLCH_1:
case RTFParserState::RunType::RTLCH_LTRCH_2:
default:
nSprm = NS_ooxml::LN_EG_RPrBase_i;
break;
}
break; break;
case RTF_OUTL: case RTF_OUTL:
nSprm = NS_ooxml::LN_EG_RPrBase_outline; nSprm = NS_ooxml::LN_EG_RPrBase_outline;
...@@ -1950,7 +1974,11 @@ RTFError RTFDocumentImpl::pushState() ...@@ -1950,7 +1974,11 @@ RTFError RTFDocumentImpl::pushState()
else else
{ {
// fdo#85812 group resets run type of _current_ and new state (but not RTL) // fdo#85812 group resets run type of _current_ and new state (but not RTL)
m_aStates.top().setRunType(RTFParserState::RunType::LOCH); if (m_aStates.top().getRunType() != RTFParserState::RunType::LTRCH_RTLCH_2
&& m_aStates.top().getRunType() != RTFParserState::RunType::RTLCH_LTRCH_2)
{
m_aStates.top().setRunType(RTFParserState::RunType::NONE);
}
if (m_aStates.top().getDestination() == Destination::MR) if (m_aStates.top().getDestination() == Destination::MR)
lcl_DestinationToMath(m_aStates.top().getCurrentDestinationText(), m_aMathBuffer, lcl_DestinationToMath(m_aStates.top().getCurrentDestinationText(), m_aMathBuffer,
...@@ -3567,8 +3595,7 @@ RTFParserState::RTFParserState(RTFDocumentImpl* pDocumentImpl) ...@@ -3567,8 +3595,7 @@ RTFParserState::RTFParserState(RTFDocumentImpl* pDocumentImpl)
, m_nListLevelNum(0) , m_nListLevelNum(0)
, m_bLevelNumbersValid(true) , m_bLevelNumbersValid(true)
, m_aFrame(this) , m_aFrame(this)
, m_eRunType(RunType::LOCH) , m_eRunType(RunType::NONE)
, m_bIsRightToLeft(false)
, m_nYear(0) , m_nYear(0)
, m_nMonth(0) , m_nMonth(0)
, m_nDay(0) , m_nDay(0)
......
...@@ -401,9 +401,14 @@ public: ...@@ -401,9 +401,14 @@ public:
/// Maps to OOXML's ascii, cs or eastAsia. /// Maps to OOXML's ascii, cs or eastAsia.
enum class RunType enum class RunType
{ {
NONE,
LOCH, LOCH,
HICH, HICH,
DBCH DBCH,
LTRCH_RTLCH_1,
LTRCH_RTLCH_2,
RTLCH_LTRCH_1,
RTLCH_LTRCH_2
}; };
explicit RTFParserState(RTFDocumentImpl* pDocumentImpl); explicit RTFParserState(RTFDocumentImpl* pDocumentImpl);
...@@ -475,8 +480,6 @@ public: ...@@ -475,8 +480,6 @@ public:
sal_uInt16 getMonth() const { return m_nMonth; } sal_uInt16 getMonth() const { return m_nMonth; }
void setYear(sal_uInt16 nYear) { m_nYear = nYear; } void setYear(sal_uInt16 nYear) { m_nYear = nYear; }
sal_uInt16 getYear() const { return m_nYear; } sal_uInt16 getYear() const { return m_nYear; }
void setIsRightToLeft(bool bIsRightToLeft) { m_bIsRightToLeft = bIsRightToLeft; }
bool getIsRightToLeft() const { return m_bIsRightToLeft; }
void setRunType(RunType eRunType) { m_eRunType = eRunType; } void setRunType(RunType eRunType) { m_eRunType = eRunType; }
RunType getRunType() const { return m_eRunType; } RunType getRunType() const { return m_eRunType; }
RTFFrame& getFrame() { return m_aFrame; } RTFFrame& getFrame() { return m_aFrame; }
...@@ -578,8 +581,6 @@ private: ...@@ -578,8 +581,6 @@ private:
RTFFrame m_aFrame; RTFFrame m_aFrame;
RunType m_eRunType; RunType m_eRunType;
/// ltrch or rtlch
bool m_bIsRightToLeft;
// Info group. // Info group.
sal_Int16 m_nYear; sal_Int16 m_nYear;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment