Kaydet (Commit) f10404e3 authored tarafından Justin Luth's avatar Justin Luth Kaydeden (comit) Miklos Vajna

tdf#121110 ww8import Jc80 justify is absolute, not Bidi relative

Paragraph justification can be specified either absolutely
(in old versions or with eWW8:Jc80) or relatively (with eWW8:Jc).
The last processed SPRM wins (I assume).

The WW8 format seems to ALWAYS specify Jc80,
and that is overwritten by an optional Jc SPRM.
I haven't seen Jc be processed before a Jc80 SPRM,
but if it does, then the justify would need to be treated as absolute.

If for some reason neither of these exist, BiDi will adjust by default
only if it is the newer WW8 format. Again, that is an assumption
because I haven't seen such a document to test.

Change-Id: I966077d743f1d148fe2fb9faba87fbdd8f3507f3
Reviewed-on: https://gerrit.libreoffice.org/63591
Tested-by: Jenkins
Reviewed-by: 's avatarJustin Luth <justin_luth@sil.org>
Reviewed-by: 's avatarMiklos Vajna <vmiklos@collabora.com>
üst bdc82e27
This diff was suppressed by a .gitattributes entry.
...@@ -262,6 +262,12 @@ DECLARE_WW8EXPORT_TEST(testTdf98620_rtlJustify, "tdf98620_rtlJustify.doc") ...@@ -262,6 +262,12 @@ DECLARE_WW8EXPORT_TEST(testTdf98620_rtlJustify, "tdf98620_rtlJustify.doc")
CPPUNIT_ASSERT_EQUAL( style::ParagraphAdjust_RIGHT, static_cast<style::ParagraphAdjust>(getProperty<sal_Int16>(getParagraph(1), "ParaAdjust")) ); CPPUNIT_ASSERT_EQUAL( style::ParagraphAdjust_RIGHT, static_cast<style::ParagraphAdjust>(getProperty<sal_Int16>(getParagraph(1), "ParaAdjust")) );
} }
DECLARE_WW8EXPORT_TEST(testTdf121110_absJustify, "tdf121110_absJustify.doc")
{
CPPUNIT_ASSERT_EQUAL( style::ParagraphAdjust_RIGHT, static_cast<style::ParagraphAdjust>(getProperty<sal_Int16>(getParagraph(1), "ParaAdjust")) );
CPPUNIT_ASSERT_EQUAL( style::ParagraphAdjust_LEFT, static_cast<style::ParagraphAdjust>(getProperty<sal_Int16>(getParagraph(3), "ParaAdjust")) );
}
DECLARE_WW8EXPORT_TEST(testTdf106174_rtlParaAlign, "tdf106174_rtlParaAlign.docx") DECLARE_WW8EXPORT_TEST(testTdf106174_rtlParaAlign, "tdf106174_rtlParaAlign.docx")
{ {
CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_CENTER), getProperty<sal_Int16>(getParagraph(1), "ParaAdjust")); CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_CENTER), getProperty<sal_Int16>(getParagraph(1), "ParaAdjust"));
......
...@@ -253,6 +253,7 @@ public: ...@@ -253,6 +253,7 @@ public:
//for L of the LR space independently //for L of the LR space independently
bool m_bParaAutoBefore; // For Auto spacing before a paragraph bool m_bParaAutoBefore; // For Auto spacing before a paragraph
bool m_bParaAutoAfter; // For Auto Spacing after a paragraph bool m_bParaAutoAfter; // For Auto Spacing after a paragraph
sal_Int16 m_nRelativeJustify;
SwWW8StyInf() : SwWW8StyInf() :
m_sWWStyleName( OUString() ), m_sWWStyleName( OUString() ),
...@@ -279,7 +280,8 @@ public: ...@@ -279,7 +280,8 @@ public:
m_bHasBrokenWW6List(false), m_bHasBrokenWW6List(false),
m_bListReleventIndentSet(false), m_bListReleventIndentSet(false),
m_bParaAutoBefore(false), m_bParaAutoBefore(false),
m_bParaAutoAfter(false) m_bParaAutoAfter(false),
m_nRelativeJustify(-1)
{} {}
...@@ -1747,7 +1749,12 @@ public: // really private, but can only be done public ...@@ -1747,7 +1749,12 @@ public: // really private, but can only be done public
void Read_ParaAutoAfter(sal_uInt16 , const sal_uInt8 *pData, short nLen); void Read_ParaAutoAfter(sal_uInt16 , const sal_uInt8 *pData, short nLen);
void Read_ParaContextualSpacing( sal_uInt16 nId, const sal_uInt8* pData, short nLen ); void Read_ParaContextualSpacing( sal_uInt16 nId, const sal_uInt8* pData, short nLen );
void Read_LineSpace( sal_uInt16, const sal_uInt8*, short nLen ); void Read_LineSpace( sal_uInt16, const sal_uInt8*, short nLen );
void SetRelativeJustify( bool bRel );
bool IsRelativeJustify();
bool IsRelativeJustify( sal_uInt16 nColl );
void Read_Justify(sal_uInt16, const sal_uInt8*, short nLen); void Read_Justify(sal_uInt16, const sal_uInt8*, short nLen);
void Read_IdctHint(sal_uInt16, const sal_uInt8*, short nLen); void Read_IdctHint(sal_uInt16, const sal_uInt8*, short nLen);
bool IsRightToLeft(); bool IsRightToLeft();
void Read_RTLJustify(sal_uInt16, const sal_uInt8*, short nLen); void Read_RTLJustify(sal_uInt16, const sal_uInt8*, short nLen);
......
...@@ -310,6 +310,59 @@ void SwWW8ImplReader::SetDocumentGrid(SwFrameFormat &rFormat, const wwSection &r ...@@ -310,6 +310,59 @@ void SwWW8ImplReader::SetDocumentGrid(SwFrameFormat &rFormat, const wwSection &r
rFormat.SetFormatAttr(aGrid); rFormat.SetFormatAttr(aGrid);
} }
void SwWW8ImplReader::SetRelativeJustify( bool bRel )
{
if ( m_pCurrentColl && StyleExists(m_nCurrentColl) ) // importing style
m_vColl[m_nCurrentColl].m_nRelativeJustify = bRel ? 1 : 0;
else if ( m_xPlcxMan && m_xPlcxMan->GetPap() ) // importing paragraph
m_xPlcxMan->GetPap()->nRelativeJustify = bRel ? 1 : 0;
}
bool SwWW8ImplReader::IsRelativeJustify()
{
bool bRet = m_xWwFib->GetFIBVersion() >= ww::eWW8;
if ( bRet )
{
// if relativeJustify is undefined (-1), then check the parent style.
if ( m_pCurrentColl && StyleExists(m_nCurrentColl) )
{
sal_Int16 nRelative = m_vColl[m_nCurrentColl].m_nRelativeJustify;
if ( nRelative < 0 && m_nCurrentColl )
bRet = IsRelativeJustify( m_vColl[m_nCurrentColl].m_nBase );
else
bRet = nRelative > 0;
}
else if ( m_xPlcxMan && m_xPlcxMan->GetPap() )
{
sal_Int16 nRelative = m_xPlcxMan->GetPap()->nRelativeJustify;
if ( nRelative < 0 )
bRet = IsRelativeJustify( m_nCurrentColl );
else
bRet = nRelative > 0;
}
}
return bRet;
}
bool SwWW8ImplReader::IsRelativeJustify( sal_uInt16 nColl )
{
assert( m_xWwFib->GetFIBVersion() >= ww::eWW8
&& "pointless to search styles if relative justify is impossible");
bool bRet = true;
if ( StyleExists(nColl) )
{
// if relativeJustify is undefined (-1), then check the parent style.
sal_Int16 nRelative = m_vColl[nColl].m_nRelativeJustify;
if ( nColl == 0 || nRelative >= 0 )
bRet = nRelative > 0;
else if ( nColl != m_vColl[nColl].m_nBase )
bRet = IsRelativeJustify( m_vColl[nColl].m_nBase );
}
return bRet;
}
void SwWW8ImplReader::Read_ParaBiDi(sal_uInt16, const sal_uInt8* pData, short nLen) void SwWW8ImplReader::Read_ParaBiDi(sal_uInt16, const sal_uInt8* pData, short nLen)
{ {
if (nLen < 1) if (nLen < 1)
...@@ -319,11 +372,17 @@ void SwWW8ImplReader::Read_ParaBiDi(sal_uInt16, const sal_uInt8* pData, short nL ...@@ -319,11 +372,17 @@ void SwWW8ImplReader::Read_ParaBiDi(sal_uInt16, const sal_uInt8* pData, short nL
SvxFrameDirection eDir = SvxFrameDirection eDir =
*pData ? SvxFrameDirection::Horizontal_RL_TB : SvxFrameDirection::Horizontal_LR_TB; *pData ? SvxFrameDirection::Horizontal_RL_TB : SvxFrameDirection::Horizontal_LR_TB;
// Previous adjust or bidi values require changing paraAdjust. // In eWW8+, justify can be absolute, or relative to BiDi
// Only change if ParaBiDi doesn't match previous setting. bool bBiDiSwap = IsRelativeJustify();
const bool bParentRTL = IsRightToLeft(); if ( bBiDiSwap )
if ( (eDir == SvxFrameDirection::Horizontal_RL_TB && !bParentRTL) || {
(eDir == SvxFrameDirection::Horizontal_LR_TB && bParentRTL) ) // Only change if ParaBiDi doesn't match previous setting.
const bool bParentRTL = IsRightToLeft();
bBiDiSwap = (eDir == SvxFrameDirection::Horizontal_RL_TB && !bParentRTL)
|| (eDir == SvxFrameDirection::Horizontal_LR_TB && bParentRTL);
}
if ( bBiDiSwap )
{ {
const SvxAdjustItem* pItem = static_cast<const SvxAdjustItem*>(GetFormatAttr(RES_PARATR_ADJUST)); const SvxAdjustItem* pItem = static_cast<const SvxAdjustItem*>(GetFormatAttr(RES_PARATR_ADJUST));
if ( !pItem ) if ( !pItem )
...@@ -4412,7 +4471,7 @@ void SwWW8ImplReader::Read_IdctHint( sal_uInt16, const sal_uInt8* pData, short n ...@@ -4412,7 +4471,7 @@ void SwWW8ImplReader::Read_IdctHint( sal_uInt16, const sal_uInt8* pData, short n
} }
} }
void SwWW8ImplReader::Read_Justify( sal_uInt16, const sal_uInt8* pData, short nLen ) void SwWW8ImplReader::Read_Justify( sal_uInt16 nId, const sal_uInt8* pData, short nLen )
{ {
if (nLen < 1) if (nLen < 1)
{ {
...@@ -4446,6 +4505,7 @@ void SwWW8ImplReader::Read_Justify( sal_uInt16, const sal_uInt8* pData, short nL ...@@ -4446,6 +4505,7 @@ void SwWW8ImplReader::Read_Justify( sal_uInt16, const sal_uInt8* pData, short nL
aAdjust.SetLastBlock(SvxAdjust::Block); aAdjust.SetLastBlock(SvxAdjust::Block);
NewAttr(aAdjust); NewAttr(aAdjust);
SetRelativeJustify( nId != NS_sprm::sprmPJc80 );
} }
bool SwWW8ImplReader::IsRightToLeft() bool SwWW8ImplReader::IsRightToLeft()
...@@ -4466,7 +4526,7 @@ bool SwWW8ImplReader::IsRightToLeft() ...@@ -4466,7 +4526,7 @@ bool SwWW8ImplReader::IsRightToLeft()
return bRTL; return bRTL;
} }
void SwWW8ImplReader::Read_RTLJustify( sal_uInt16, const sal_uInt8* pData, short nLen ) void SwWW8ImplReader::Read_RTLJustify( sal_uInt16 nId, const sal_uInt8* pData, short nLen )
{ {
if (nLen < 1) if (nLen < 1)
{ {
...@@ -4477,7 +4537,7 @@ void SwWW8ImplReader::Read_RTLJustify( sal_uInt16, const sal_uInt8* pData, short ...@@ -4477,7 +4537,7 @@ void SwWW8ImplReader::Read_RTLJustify( sal_uInt16, const sal_uInt8* pData, short
//If we are in a ltr paragraph this is the same as normal Justify, //If we are in a ltr paragraph this is the same as normal Justify,
//If we are in a rtl paragraph the meaning is reversed. //If we are in a rtl paragraph the meaning is reversed.
if (!IsRightToLeft()) if (!IsRightToLeft())
Read_Justify(NS_sprm::sprmPJc80 /*dummy*/, pData, nLen); Read_Justify(nId, pData, nLen);
else else
{ {
SvxAdjust eAdjust(SvxAdjust::Right); SvxAdjust eAdjust(SvxAdjust::Right);
...@@ -4506,6 +4566,7 @@ void SwWW8ImplReader::Read_RTLJustify( sal_uInt16, const sal_uInt8* pData, short ...@@ -4506,6 +4566,7 @@ void SwWW8ImplReader::Read_RTLJustify( sal_uInt16, const sal_uInt8* pData, short
aAdjust.SetLastBlock(SvxAdjust::Block); aAdjust.SetLastBlock(SvxAdjust::Block);
NewAttr(aAdjust); NewAttr(aAdjust);
SetRelativeJustify( true );
} }
} }
......
...@@ -903,6 +903,7 @@ struct WW8PLCFxDesc ...@@ -903,6 +903,7 @@ struct WW8PLCFxDesc
long nCpOfs; // for Offset Header .. Footnote long nCpOfs; // for Offset Header .. Footnote
bool bFirstSprm; // for recognizing the first Sprm of a group bool bFirstSprm; // for recognizing the first Sprm of a group
bool bRealLineEnd; // false for Pap-Piece-end bool bRealLineEnd; // false for Pap-Piece-end
sal_Int16 nRelativeJustify;
void Save( WW8PLCFxSave1& rSave ) const; void Save( WW8PLCFxSave1& rSave ) const;
void Restore( const WW8PLCFxSave1& rSave ); void Restore( const WW8PLCFxSave1& rSave );
//With nStartPos set to WW8_CP_MAX then in the case of a pap or chp //With nStartPos set to WW8_CP_MAX then in the case of a pap or chp
...@@ -922,6 +923,7 @@ struct WW8PLCFxDesc ...@@ -922,6 +923,7 @@ struct WW8PLCFxDesc
, nCpOfs(0) , nCpOfs(0)
, bFirstSprm(false) , bFirstSprm(false)
, bRealLineEnd(false) , bRealLineEnd(false)
, nRelativeJustify(-1)
{ {
} }
void ReduceByOffset(); void ReduceByOffset();
......
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