tdf#173649 sw: don't wrap docx text into a narrow gap beside a shape
Writer laid text into a 0.2 cm gap left of a text box, where Word leaves the gap empty. Word gives up a gap under a quarter inch wide, measured from the column edge to the object's wrap boundary, when the other side has at least that much room. Follow the same rule for documents the Word filters read. Change-Id: Ifdacbf0469296ade1665fb0b56526301cd19f973 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/211280 Reviewed-by: Samuel Mehrbrodt <samuel.mehrbrodt@collabora.com> Tested-by: Jenkins
This commit is contained in:
@@ -71,6 +71,7 @@ enum class DocumentSettingId
|
||||
MS_WORD_COMP_TRAILING_BLANKS,
|
||||
// tdf#128197 MS Word in some modes can have line height based on shape height, not on font
|
||||
MS_WORD_COMP_MIN_LINE_HEIGHT_BY_FLY,
|
||||
MS_WORD_COMP_MIN_TEXT_WRAP_GAP,
|
||||
UNIX_FORCE_ZERO_EXT_LEADING,
|
||||
TABS_RELATIVE_TO_INDENT,
|
||||
PROTECT_FORM,
|
||||
|
||||
Binary file not shown.
@@ -29,6 +29,25 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(Test, testMinWrapGap)
|
||||
{
|
||||
// Given a document with a square-wrapped shape
|
||||
createSwDoc("min-wrap-gap.docx");
|
||||
|
||||
// When layouting that document
|
||||
calcLayout();
|
||||
|
||||
// Then make sure the line starts with the fly portion
|
||||
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
||||
// Without the fix, this test would have failed with:
|
||||
// - Expected: PortionType::Fly
|
||||
// - Actual: PortionType::Text
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/*[1]", "type",
|
||||
u"PortionType::Fly");
|
||||
// The paragraph below the shape should not be affected
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[5]/SwParaPortion/SwLineLayout/SwFixPortion", 0);
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(Test, testClearingBreakWrapThrough)
|
||||
{
|
||||
// Given a document with a clearing break, then a shape in the next paragraph:
|
||||
|
||||
@@ -80,6 +80,7 @@ sw::DocumentSettingManager::DocumentSettingManager(SwDoc &rDoc)
|
||||
mbTabRelativeToIndent(true),
|
||||
mbProtectForm(false), // i#78591#
|
||||
mbMsWordCompTrailingBlanks(false), // tdf#104349 tdf#104668
|
||||
mbMsWordCompMinTextWrapGap(false),
|
||||
mbMsWordCompMinLineHeightByFly(false),
|
||||
mbInvertBorderSpacing (false),
|
||||
mbCollapseEmptyCellPara(true),
|
||||
@@ -221,6 +222,7 @@ bool sw::DocumentSettingManager::get(/*[in]*/ DocumentSettingId id) const
|
||||
case DocumentSettingId::PROTECT_FORM: return mbProtectForm;
|
||||
// tdf#104349 tdf#104668
|
||||
case DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS: return mbMsWordCompTrailingBlanks;
|
||||
case DocumentSettingId::MS_WORD_COMP_MIN_TEXT_WRAP_GAP: return mbMsWordCompMinTextWrapGap;
|
||||
case DocumentSettingId::MS_WORD_COMP_MIN_LINE_HEIGHT_BY_FLY: return mbMsWordCompMinLineHeightByFly;
|
||||
// #i89181#
|
||||
case DocumentSettingId::TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST: return mbTabAtLeftIndentForParagraphsInList;
|
||||
@@ -416,6 +418,10 @@ void sw::DocumentSettingManager::set(/*[in]*/ DocumentSettingId id, /*[in]*/ boo
|
||||
mbMsWordCompTrailingBlanks = value;
|
||||
break;
|
||||
|
||||
case DocumentSettingId::MS_WORD_COMP_MIN_TEXT_WRAP_GAP:
|
||||
mbMsWordCompMinTextWrapGap = value;
|
||||
break;
|
||||
|
||||
case DocumentSettingId::MS_WORD_COMP_MIN_LINE_HEIGHT_BY_FLY:
|
||||
mbMsWordCompMinLineHeightByFly = value;
|
||||
break;
|
||||
@@ -806,6 +812,7 @@ void sw::DocumentSettingManager::ReplaceCompatibilityOptions(const DocumentSetti
|
||||
mbTabRelativeToIndent = rSource.mbTabRelativeToIndent;
|
||||
mbProtectForm = rSource.mbProtectForm;
|
||||
mbMsWordCompTrailingBlanks = rSource.mbMsWordCompTrailingBlanks;
|
||||
mbMsWordCompMinTextWrapGap = rSource.mbMsWordCompMinTextWrapGap;
|
||||
mbMsWordCompMinLineHeightByFly = rSource.mbMsWordCompMinLineHeightByFly;
|
||||
mbInvertBorderSpacing = rSource.mbInvertBorderSpacing;
|
||||
mbCollapseEmptyCellPara = rSource.mbCollapseEmptyCellPara;
|
||||
@@ -1068,6 +1075,11 @@ void sw::DocumentSettingManager::dumpAsXml(xmlTextWriterPtr pWriter) const
|
||||
BAD_CAST(OString::boolean(mbMsWordCompTrailingBlanks).getStr()));
|
||||
(void)xmlTextWriterEndElement(pWriter);
|
||||
|
||||
(void)xmlTextWriterStartElement(pWriter, BAD_CAST("mbMsWordCompMinTextWrapGap"));
|
||||
(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"),
|
||||
BAD_CAST(OString::boolean(mbMsWordCompMinTextWrapGap).getStr()));
|
||||
(void)xmlTextWriterEndElement(pWriter);
|
||||
|
||||
(void)xmlTextWriterStartElement(pWriter, BAD_CAST("mbMsWordCompMinLineHeightByFly"));
|
||||
(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"),
|
||||
BAD_CAST(OString::boolean(mbMsWordCompMinLineHeightByFly).getStr()));
|
||||
|
||||
@@ -143,6 +143,7 @@ class DocumentSettingManager final :
|
||||
bool mbTabRelativeToIndent : 1; // #i24363# tab stops relative to indent
|
||||
bool mbProtectForm : 1;
|
||||
bool mbMsWordCompTrailingBlanks : 1; // tdf#104349 tdf#104668
|
||||
bool mbMsWordCompMinTextWrapGap : 1;
|
||||
bool mbMsWordCompMinLineHeightByFly : 1;
|
||||
bool mbInvertBorderSpacing : 1;
|
||||
bool mbCollapseEmptyCellPara : 1;
|
||||
|
||||
@@ -1479,6 +1479,10 @@ SwRect SwTextFly::AnchoredObjToRect( const SwAnchoredObject* pAnchoredObj,
|
||||
// Wrap on both sides up to a frame width of 1.5cm
|
||||
#define FRAME_MAX 850
|
||||
|
||||
// Word gives up a side narrower than 1/4 inch, measured from the column edge, when the
|
||||
// other side has that much room. With both sides narrow it wraps on both.
|
||||
#define WORD_TEXT_MIN 360
|
||||
|
||||
css::text::WrapTextMode SwTextFly::GetSurroundForTextWrap( const SwAnchoredObject* pAnchoredObj ) const
|
||||
{
|
||||
const SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat();
|
||||
@@ -1553,6 +1557,25 @@ css::text::WrapTextMode SwTextFly::GetSurroundForTextWrap( const SwAnchoredObjec
|
||||
}
|
||||
}
|
||||
|
||||
// Ask the format rather than eSurroundForTextWrap, because an optimal wrap
|
||||
// which the branch above turned into a parallel one measures its sides
|
||||
// against the paragraph and keeps that result.
|
||||
if (css::text::WrapTextMode_PARALLEL == rFlyFormat.GetSurround()
|
||||
&& GetMaster()->GetDoc().getIDocumentSettingAccess().get(
|
||||
DocumentSettingId::MS_WORD_COMP_MIN_TEXT_WRAP_GAP))
|
||||
{
|
||||
SwRectFnSet aRectFnSet(*m_pCurrFrame);
|
||||
const SwRect& rObj(pAnchoredObj->GetObjRectWithSpaces());
|
||||
const SwRect& rCol(m_pCurrFrame->getFrameArea());
|
||||
const tools::Long nLeft = aRectFnSet.GetLeft(rObj) - aRectFnSet.GetLeft(rCol);
|
||||
const tools::Long nRight = aRectFnSet.GetRight(rCol) - aRectFnSet.GetRight(rObj);
|
||||
// If neither side has enough space, keep the wrap mode as PARALLEL
|
||||
if (nLeft < WORD_TEXT_MIN && nRight >= WORD_TEXT_MIN)
|
||||
eSurroundForTextWrap = css::text::WrapTextMode_RIGHT;
|
||||
else if (nRight < WORD_TEXT_MIN && nLeft >= WORD_TEXT_MIN)
|
||||
eSurroundForTextWrap = css::text::WrapTextMode_LEFT;
|
||||
}
|
||||
|
||||
return eSurroundForTextWrap;
|
||||
}
|
||||
|
||||
|
||||
@@ -1954,6 +1954,8 @@ void SwWW8ImplReader::ImportDop()
|
||||
DocumentSettingId::APPLY_PARAGRAPH_MARK_FORMAT_TO_NUMBERING, true);
|
||||
m_rDoc.getIDocumentSettingAccess().set(
|
||||
DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS, true);
|
||||
m_rDoc.getIDocumentSettingAccess().set(
|
||||
DocumentSettingId::MS_WORD_COMP_MIN_TEXT_WRAP_GAP, true);
|
||||
// tdf#128195
|
||||
m_rDoc.getIDocumentSettingAccess().set(
|
||||
DocumentSettingId::HEADER_SPACING_BELOW_LAST_PARA, true);
|
||||
|
||||
@@ -114,6 +114,7 @@ enum SwDocumentSettingsPropertyHandles
|
||||
HANDLE_USE_OLD_PRINTER_METRICS,
|
||||
HANDLE_PROTECT_FORM,
|
||||
HANDLE_MS_WORD_COMP_TRAILING_BLANKS,
|
||||
HANDLE_MS_WORD_COMP_MIN_TEXT_WRAP_GAP,
|
||||
HANDLE_MS_WORD_COMP_MIN_LINE_HEIGHT_BY_FLY,
|
||||
HANDLE_TABS_RELATIVE_TO_INDENT,
|
||||
HANDLE_RSID,
|
||||
@@ -237,6 +238,7 @@ static rtl::Reference<MasterPropertySetInfo> lcl_createSettingsInfo()
|
||||
{ u"RsidRoot"_ustr, HANDLE_RSID_ROOT, cppu::UnoType<sal_Int32>::get(), 0},
|
||||
{ u"ProtectForm"_ustr, HANDLE_PROTECT_FORM, cppu::UnoType<bool>::get(), 0},
|
||||
{ u"MsWordCompTrailingBlanks"_ustr, HANDLE_MS_WORD_COMP_TRAILING_BLANKS, cppu::UnoType<bool>::get(), 0 },
|
||||
{ u"MsWordCompMinTextWrapGap"_ustr, HANDLE_MS_WORD_COMP_MIN_TEXT_WRAP_GAP, cppu::UnoType<bool>::get(), 0 },
|
||||
{ u"MsWordCompMinLineHeightByFly"_ustr, HANDLE_MS_WORD_COMP_MIN_LINE_HEIGHT_BY_FLY, cppu::UnoType<bool>::get(), 0 },
|
||||
{ u"TabAtLeftIndentForParagraphsInList"_ustr, HANDLE_TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST, cppu::UnoType<bool>::get(), 0},
|
||||
{ u"ModifyPasswordInfo"_ustr, HANDLE_MODIFYPASSWORDINFO, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), 0},
|
||||
@@ -825,6 +827,12 @@ void SwXDocumentSettings::_setSingleValue( const comphelper::PropertyInfo & rInf
|
||||
mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS, bTmp);
|
||||
}
|
||||
break;
|
||||
case HANDLE_MS_WORD_COMP_MIN_TEXT_WRAP_GAP:
|
||||
{
|
||||
bool bTmp = *o3tl::doAccess<bool>(rValue);
|
||||
mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::MS_WORD_COMP_MIN_TEXT_WRAP_GAP, bTmp);
|
||||
}
|
||||
break;
|
||||
case HANDLE_MS_WORD_COMP_MIN_LINE_HEIGHT_BY_FLY:
|
||||
{
|
||||
bool bTmp = *o3tl::doAccess<bool>(rValue);
|
||||
@@ -1618,6 +1626,11 @@ void SwXDocumentSettings::_getSingleValue( const comphelper::PropertyInfo & rInf
|
||||
rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS);
|
||||
}
|
||||
break;
|
||||
case HANDLE_MS_WORD_COMP_MIN_TEXT_WRAP_GAP:
|
||||
{
|
||||
rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::MS_WORD_COMP_MIN_TEXT_WRAP_GAP);
|
||||
}
|
||||
break;
|
||||
case HANDLE_MS_WORD_COMP_MIN_LINE_HEIGHT_BY_FLY:
|
||||
{
|
||||
rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::MS_WORD_COMP_MIN_LINE_HEIGHT_BY_FLY);
|
||||
|
||||
@@ -675,6 +675,7 @@ void SettingsTable::ApplyProperties(rtl::Reference<SwXTextDocument> const& xDoc)
|
||||
|
||||
// Shared between DOCX and RTF, unconditional flags.
|
||||
xDocumentSettings->setPropertyValue(u"TableRowKeep"_ustr, uno::Any(true));
|
||||
xDocumentSettings->setPropertyValue(u"MsWordCompMinTextWrapGap"_ustr, uno::Any(true));
|
||||
xDocumentSettings->setPropertyValue(u"AddVerticalFrameOffsets"_ustr, uno::Any(true));
|
||||
xDocumentSettings->setPropertyValue(u"ApplyParagraphMarkFormatToEmptyLineAtEndOfParagraph"_ustr,
|
||||
uno::Any(true));
|
||||
|
||||
Reference in New Issue
Block a user