summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editeng/source/items/frmitems.cxx50
-rw-r--r--include/editeng/lrspitem.hxx10
-rw-r--r--include/editeng/memberids.h1
-rw-r--r--include/xmloff/xmltypes.hxx1
-rw-r--r--schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng19
-rw-r--r--sw/inc/unoprnms.hxx1
-rw-r--r--sw/qa/extras/odfexport/data/tdf36709.fodt117
-rw-r--r--sw/qa/extras/odfexport/odfexport2.cxx19
-rw-r--r--sw/source/core/text/itrcrsr.cxx20
-rw-r--r--sw/source/core/unocore/unomap1.cxx1
-rw-r--r--sw/source/core/unocore/unomapproperties.hxx3
-rw-r--r--vcl/qa/cppunit/pdfexport/data/tdf36709.fodt151
-rw-r--r--vcl/qa/cppunit/pdfexport/pdfexport2.cxx51
-rw-r--r--xmloff/inc/xmlbahdl.hxx10
-rw-r--r--xmloff/inc/xmlprop.hxx1
-rw-r--r--xmloff/source/style/prhdlfac.cxx3
-rw-r--r--xmloff/source/style/xmlbahdl.cxx53
-rw-r--r--xmloff/source/text/txtprmap.cxx3
18 files changed, 510 insertions, 4 deletions
diff --git a/editeng/source/items/frmitems.cxx b/editeng/source/items/frmitems.cxx
index 5dd0346ef47e..93d1c33fcc8f 100644
--- a/editeng/source/items/frmitems.cxx
+++ b/editeng/source/items/frmitems.cxx
@@ -28,6 +28,7 @@
#include <com/sun/star/style/BreakType.hpp>
#include <com/sun/star/style/GraphicLocation.hpp>
#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/beans/Pair.hpp>
#include <com/sun/star/text/WritingMode2.hpp>
#include <com/sun/star/frame/status/UpperLowerMarginScale.hpp>
#include <com/sun/star/frame/status/LeftRightMarginScale.hpp>
@@ -500,6 +501,7 @@ void SvxFirstLineIndentItem::SetTextFirstLineOffset(
{
ASSERT_CHANGE_REFCOUNTED_ITEM;
m_nFirstLineOffset = short((tools::Long(nF) * nProp ) / 100);
+ m_nUnit = css::util::MeasureUnit::TWIP;
m_nPropFirstLineOffset = nProp;
}
@@ -944,20 +946,45 @@ SvxFirstLineIndentItem::SvxFirstLineIndentItem(const short nFirst, const sal_uIn
bool SvxFirstLineIndentItem::QueryValue(uno::Any& rVal, sal_uInt8 nMemberId) const
{
- bool bRet = true;
+ bool bRet = false;
bool bConvert = 0 != (nMemberId & CONVERT_TWIPS);
nMemberId &= ~CONVERT_TWIPS;
switch (nMemberId)
{
case MID_FIRST_LINE_INDENT:
- rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(m_nFirstLineOffset) : m_nFirstLineOffset);
- break;
+ // MID_FIRST_LINE_INDENT only supports statically-convertible measures.
+ // In practice, these are always stored here in twips.
+ if (m_nUnit == css::util::MeasureUnit::TWIP)
+ {
+ rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(m_nFirstLineOffset)
+ : m_nFirstLineOffset);
+ bRet = true;
+ }
+ break;
+
case MID_FIRST_LINE_REL_INDENT:
rVal <<= static_cast<sal_Int16>(m_nPropFirstLineOffset);
+ bRet = true;
break;
+
+ case MID_FIRST_LINE_UNIT_INDENT:
+ // MID_FIRST_LINE_UNIT_INDENT is used for any values that must be serialized
+ // as a unit-value pair. In practice, this will be limited to font-relative
+ // units (e.g. em, ic), and all other units will be pre-converted to twips.
+ if (m_nUnit != css::util::MeasureUnit::TWIP)
+ {
+ rVal <<= css::beans::Pair<double, sal_Int16>{
+ static_cast<double>(m_nFirstLineOffset), m_nUnit
+ };
+ bRet = true;
+ }
+ break;
+
case MID_FIRST_AUTO:
rVal <<= IsAutoFirst();
+ bRet = true;
break;
+
default:
assert(false);
bRet = false;
@@ -983,6 +1010,7 @@ bool SvxFirstLineIndentItem::PutValue(const uno::Any& rVal, sal_uInt8 nMemberId)
return false;
}
m_nFirstLineOffset = bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal;
+ m_nUnit = css::util::MeasureUnit::TWIP;
m_nPropFirstLineOffset = 100;
break;
}
@@ -999,6 +1027,19 @@ bool SvxFirstLineIndentItem::PutValue(const uno::Any& rVal, sal_uInt8 nMemberId)
}
break;
}
+ case MID_FIRST_LINE_UNIT_INDENT:
+ {
+ css::beans::Pair<double, sal_Int16> stVal;
+ if (!(rVal >>= stVal))
+ {
+ return false;
+ }
+
+ m_nFirstLineOffset = stVal.First;
+ m_nUnit = stVal.Second;
+ m_nPropFirstLineOffset = 100;
+ break;
+ }
case MID_FIRST_AUTO:
SetAutoFirst(Any2Bool(rVal));
break;
@@ -1017,6 +1058,7 @@ bool SvxFirstLineIndentItem::operator==(const SfxPoolItem& rAttr) const
const SvxFirstLineIndentItem& rOther = static_cast<const SvxFirstLineIndentItem&>(rAttr);
return (m_nFirstLineOffset == rOther.GetTextFirstLineOffset()
+ && m_nUnit == rOther.GetTextFirstLineOffsetUnit()
&& m_nPropFirstLineOffset == rOther.GetPropTextFirstLineOffset()
&& m_bAutoFirst == rOther.IsAutoFirst());
}
@@ -1025,6 +1067,7 @@ size_t SvxFirstLineIndentItem::hashCode() const
{
std::size_t seed(0);
o3tl::hash_combine(seed, m_nFirstLineOffset);
+ o3tl::hash_combine(seed, m_nUnit);
o3tl::hash_combine(seed, m_nPropFirstLineOffset);
o3tl::hash_combine(seed, m_bAutoFirst);
return seed;
@@ -1096,6 +1139,7 @@ void SvxFirstLineIndentItem::dumpAsXml(xmlTextWriterPtr pWriter) const
(void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxFirstLineIndentItem"));
(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nFirstLineOffset"), BAD_CAST(OString::number(m_nFirstLineOffset).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nUnit"), BAD_CAST(OString::number(m_nUnit).getStr()));
(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nPropFirstLineOffset"), BAD_CAST(OString::number(m_nPropFirstLineOffset).getStr()));
(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_bAutoFirst"), BAD_CAST(OString::number(int(m_bAutoFirst)).getStr()));
(void)xmlTextWriterEndElement(pWriter);
diff --git a/include/editeng/lrspitem.hxx b/include/editeng/lrspitem.hxx
index 5fe01262e7c2..63bff2c974ca 100644
--- a/include/editeng/lrspitem.hxx
+++ b/include/editeng/lrspitem.hxx
@@ -21,6 +21,7 @@
#include <svl/poolitem.hxx>
#include <editeng/editengdllapi.h>
+#include <com/sun/star/util/MeasureUnit.hpp>
// class SvxLRSpaceItem --------------------------------------------------
@@ -136,6 +137,7 @@ class EDITENG_DLLPUBLIC SvxFirstLineIndentItem final : public SfxPoolItem
private:
/// First-line indent always relative to GetTextLeft()
short m_nFirstLineOffset = 0;
+ sal_Int16 m_nUnit = css::util::MeasureUnit::TWIP;
sal_uInt16 m_nPropFirstLineOffset = 100;
/// Automatic calculation of the first line indent
bool m_bAutoFirst = false;
@@ -146,12 +148,18 @@ public:
void SetTextFirstLineOffset(const short nF, const sal_uInt16 nProp = 100);
short GetTextFirstLineOffset() const { return m_nFirstLineOffset; }
+ double GetTextFirstLineOffsetDouble() const { return m_nFirstLineOffset; }
+ sal_Int16 GetTextFirstLineOffsetUnit() const { return m_nUnit; }
void SetPropTextFirstLineOffset(const sal_uInt16 nProp)
{ ASSERT_CHANGE_REFCOUNTED_ITEM; m_nPropFirstLineOffset = nProp; }
sal_uInt16 GetPropTextFirstLineOffset() const
{ return m_nPropFirstLineOffset; }
void SetTextFirstLineOffsetValue(const short nValue)
- { ASSERT_CHANGE_REFCOUNTED_ITEM; m_nFirstLineOffset = nValue; }
+ {
+ ASSERT_CHANGE_REFCOUNTED_ITEM;
+ m_nFirstLineOffset = nValue;
+ m_nUnit = css::util::MeasureUnit::TWIP;
+ }
explicit SvxFirstLineIndentItem(const sal_uInt16 nId);
SvxFirstLineIndentItem(const short nOffset, const sal_uInt16 nId);
diff --git a/include/editeng/memberids.h b/include/editeng/memberids.h
index 57250a9872e8..195eccce41c8 100644
--- a/include/editeng/memberids.h
+++ b/include/editeng/memberids.h
@@ -138,6 +138,7 @@
#define MID_FIRST_AUTO 10
#define MID_TXT_LMARGIN 11
#define MID_GUTTER_MARGIN 12
+#define MID_FIRST_LINE_UNIT_INDENT 13
//ProtectItem
#define MID_PROTECT_CONTENT 0
diff --git a/include/xmloff/xmltypes.hxx b/include/xmloff/xmltypes.hxx
index 7c7cabb43df1..a3c6f057c610 100644
--- a/include/xmloff/xmltypes.hxx
+++ b/include/xmloff/xmltypes.hxx
@@ -154,6 +154,7 @@
#define XML_TYPE_DOUBLE_PERCENT 0x00002024 // 50% (source is a double from 0.0 to 1.0)
#define XML_TYPE_HEX 0x00002025 // 00544F1B
#define XML_TYPE_PERCENT100 0x00002026 // 100th percent
+#define XML_TYPE_UNIT_MEASURE 0x00002027 // Source is a double paired with a unit
// special basic types
#define XML_TYPE_RECTANGLE_LEFT 0x00000100 // the Left member of an awt::Rectangle as a measure
diff --git a/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng b/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng
index a805123d7e24..5f53d50c8526 100644
--- a/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng
+++ b/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng
@@ -3098,6 +3098,25 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
</rng:optional>
</rng:define>
+ <!-- https://issues.oasis-open.org/browse/OFFICE-4165 -->
+ <rng:define name="cssLength">
+ <rng:data type="string">
+ <rng:param name="pattern">-?([0-9]+(\.[0-9]*)?|\.[0-9]+)((cm)|(mm)|(in)|(pt)|(pc)|(px)|(ic)|(em))</rng:param>
+ </rng:data>
+ </rng:define>
+
+ <!-- https://issues.oasis-open.org/browse/OFFICE-4165 -->
+ <rng:define name="style-paragraph-properties-attlist" combine="interleave">
+ <rng:optional>
+ <rng:attribute name="loext:text-indent">
+ <rng:choice>
+ <rng:ref name="cssLength"/>
+ <rng:ref name="percent"/>
+ </rng:choice>
+ </rng:attribute>
+ </rng:optional>
+ </rng:define>
+
<!-- TODO no proposal -->
<rng:define name="chart-data-point-attlist" combine="interleave">
<rng:optional>
diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx
index e3d7e073c24d..13a64ef5484d 100644
--- a/sw/inc/unoprnms.hxx
+++ b/sw/inc/unoprnms.hxx
@@ -64,6 +64,7 @@ inline constexpr OUString UNO_NAME_PARA_IS_AUTO_FIRST_LINE_INDENT
inline constexpr OUString UNO_NAME_PARA_FIRST_LINE_INDENT = u"ParaFirstLineIndent"_ustr;
inline constexpr OUString UNO_NAME_PARA_FIRST_LINE_INDENT_RELATIVE
= u"ParaFirstLineIndentRelative"_ustr;
+inline constexpr OUString UNO_NAME_PARA_FIRST_LINE_INDENT_UNIT = u"ParaFirstLineIndentUnit"_ustr;
inline constexpr OUString UNO_NAME_PARA_IS_HYPHENATION = u"ParaIsHyphenation"_ustr;
inline constexpr OUString UNO_NAME_PARA_HYPHENATION_MAX_LEADING_CHARS
= u"ParaHyphenationMaxLeadingChars"_ustr;
diff --git a/sw/qa/extras/odfexport/data/tdf36709.fodt b/sw/qa/extras/odfexport/data/tdf36709.fodt
new file mode 100644
index 000000000000..f4dddd28ee85
--- /dev/null
+++ b/sw/qa/extras/odfexport/data/tdf36709.fodt
@@ -0,0 +1,117 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<office:document xmlns:css3t="http://www.w3.org/TR/css3-text/" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:rpt="http://openoffice.org/2005/report" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" office:version="1.4" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:meta><meta:creation-date>2024-10-31T15:19:06.580445570</meta:creation-date><dc:date>2024-10-31T15:22:40.161604509</dc:date><meta:editing-duration>PT3M34S</meta:editing-duration><meta:editing-cycles>1</meta:editing-cycles><meta:document-statistic meta:table-count="0" meta:image-count="0" meta:object-count="0" meta:page-count="1" meta:paragraph-count="2" meta:word-count="4" meta:character-count="42" meta:non-whitespace-character-count="40"/><meta:generator>LibreOfficeDev/25.2.0.0.alpha0$Linux_X86_64 LibreOffice_project/5f12ad737bbb930b76299df0433c8635ae27a7bd</meta:generator></office:meta>
+ <office:font-face-decls>
+ <style:font-face style:name="Liberation Serif" svg:font-family="'Liberation Serif'" style:font-family-generic="roman" style:font-pitch="variable"/>
+ <style:font-face style:name="Noto Sans1" svg:font-family="'Noto Sans'" style:font-family-generic="system" style:font-pitch="variable"/>
+ <style:font-face style:name="Noto Serif CJK SC" svg:font-family="'Noto Serif CJK SC'" style:font-family-generic="system" style:font-pitch="variable"/>
+ </office:font-face-decls>
+ <office:styles>
+ <style:default-style style:family="graphic">
+ <style:graphic-properties svg:stroke-color="#3465a4" draw:fill-color="#729fcf" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.1181in" draw:shadow-offset-y="0.1181in" draw:start-line-spacing-horizontal="0.1114in" draw:start-line-spacing-vertical="0.1114in" draw:end-line-spacing-horizontal="0.1114in" draw:end-line-spacing-vertical="0.1114in" style:flow-with-text="false"/>
+ <style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" loext:tab-stop-distance="0in" style:writing-mode="lr-tb" style:font-independent-line-spacing="false">
+ <style:tab-stops/>
+ </style:paragraph-properties>
+ <style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="en" fo:country="US" style:letter-kerning="true" style:font-name-asian="Noto Serif CJK SC" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Noto Sans1" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN"/>
+ </style:default-style>
+ <style:default-style style:family="paragraph">
+ <style:paragraph-properties fo:orphans="2" fo:widows="2" fo:hyphenation-ladder-count="no-limit" fo:hyphenation-keep="auto" loext:hyphenation-keep-type="column" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="0.4925in" style:writing-mode="page"/>
+ <style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="en" fo:country="US" style:letter-kerning="true" style:font-name-asian="Noto Serif CJK SC" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Noto Sans1" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2" loext:hyphenation-no-caps="false" loext:hyphenation-no-last-word="false" loext:hyphenation-word-char-count="5" loext:hyphenation-zone="no-limit"/>
+ </style:default-style>
+ <style:default-style style:family="table">
+ <style:table-properties table:border-model="collapsing"/>
+ </style:default-style>
+ <style:default-style style:family="table-row">
+ <style:table-row-properties fo:keep-together="auto"/>
+ </style:default-style>
+ <style:style style:name="Standard" style:family="paragraph" style:class="text"/>
+ <text:outline-style style:name="Outline">
+ <text:outline-level-style text:level="1" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="2" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="3" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="4" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="5" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="6" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="7" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="8" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="9" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="10" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ </text:outline-style>
+ <text:notes-configuration text:note-class="footnote" style:num-format="1" text:start-value="0" text:footnotes-position="page" text:start-numbering-at="document"/>
+ <text:notes-configuration text:note-class="endnote" style:num-format="i" text:start-value="0"/>
+ <text:linenumbering-configuration text:number-lines="false" text:offset="0.1965in" style:num-format="1" text:number-position="left" text:increment="5"/>
+ </office:styles>
+ <office:automatic-styles>
+ <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Standard">
+ <style:paragraph-properties loext:text-indent="3in" style:auto-text-indent="false"/>
+ <style:text-properties/>
+ </style:style>
+ <style:style style:name="P2" style:family="paragraph" style:parent-style-name="Standard">
+ <style:paragraph-properties loext:text-indent="6em" style:auto-text-indent="false"/>
+ <style:text-properties/>
+ </style:style>
+ <style:page-layout style:name="pm1">
+ <style:page-layout-properties fo:page-width="8.2681in" fo:page-height="11.6929in" style:num-format="1" style:print-orientation="portrait" fo:margin-top="0.7874in" fo:margin-bottom="0.7874in" fo:margin-left="0.7874in" fo:margin-right="0.7874in" style:writing-mode="lr-tb" style:footnote-max-height="0in" loext:margin-gutter="0in">
+ <style:footnote-sep style:width="0.0071in" style:distance-before-sep="0.0398in" style:distance-after-sep="0.0398in" style:line-style="solid" style:adjustment="left" style:rel-width="25%" style:color="#000000"/>
+ </style:page-layout-properties>
+ <style:header-style/>
+ <style:footer-style/>
+ </style:page-layout>
+ </office:automatic-styles>
+ <office:master-styles>
+ <style:master-page style:name="Standard" style:page-layout-name="pm1"/>
+ </office:master-styles>
+ <office:body>
+ <office:text>
+ <text:sequence-decls>
+ <text:sequence-decl text:display-outline-level="0" text:name="Illustration"/>
+ <text:sequence-decl text:display-outline-level="0" text:name="Table"/>
+ <text:sequence-decl text:display-outline-level="0" text:name="Text"/>
+ <text:sequence-decl text:display-outline-level="0" text:name="Drawing"/>
+ <text:sequence-decl text:display-outline-level="0" text:name="Figure"/>
+ </text:sequence-decls>
+ <text:p text:style-name="P1">3in loext:text-indent</text:p>
+ <text:p text:style-name="P2">6em loext:text-indent</text:p>
+ </office:text>
+ </office:body>
+</office:document> \ No newline at end of file
diff --git a/sw/qa/extras/odfexport/odfexport2.cxx b/sw/qa/extras/odfexport/odfexport2.cxx
index 38e4273915a4..d0353009a224 100644
--- a/sw/qa/extras/odfexport/odfexport2.cxx
+++ b/sw/qa/extras/odfexport/odfexport2.cxx
@@ -1800,6 +1800,25 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf163703)
+ autostylename.toUtf8() + "']/style:text-properties";
assertXPath(pXml, autoStyleXPath, "font-style", u"italic");
}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf36709)
+{
+ // Verifies that loext:text-indent correctly round-trips
+ loadAndReload("tdf36709.fodt");
+ CPPUNIT_ASSERT_EQUAL(1, getPages());
+ xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr);
+
+ // Style P1 should have been rewritten as fo:text-indent
+ assertXPath(pXmlDoc, "//style:style[@style:name='P1']/style:paragraph-properties[@fo:text-indent]", 1);
+ assertXPath(pXmlDoc, "//style:style[@style:name='P1']/style:paragraph-properties[@loext:text-indent]", 0);
+ assertXPath(pXmlDoc, "//style:style[@style:name='P1']/style:paragraph-properties", "text-indent", u"3in");
+
+ // Style P2 should have round-tripped as loext:text-indent
+ assertXPath(pXmlDoc, "//style:style[@style:name='P2']/style:paragraph-properties[@fo:text-indent]", 0);
+ assertXPath(pXmlDoc, "//style:style[@style:name='P2']/style:paragraph-properties[@loext:text-indent]", 1);
+ assertXPath(pXmlDoc, "//style:style[@style:name='P2']/style:paragraph-properties", "text-indent", u"6em");
+}
+
} // end of anonymous namespace
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/text/itrcrsr.cxx b/sw/source/core/text/itrcrsr.cxx
index f1db92073cba..c393154777a0 100644
--- a/sw/source/core/text/itrcrsr.cxx
+++ b/sw/source/core/text/itrcrsr.cxx
@@ -299,6 +299,26 @@ void SwTextMargin::CtorInitTextMargin( SwTextFrame *pNewFrame, SwTextSizeInfo *p
}
}
}
+ else if (!pNode->GetFirstLineOfsWithNum(nFLOfst)
+ && rFirstLine.GetTextFirstLineOffsetUnit() != css::util::MeasureUnit::TWIP)
+ {
+ auto nFntHeight = GetFnt()->GetSize(GetFnt()->GetActual()).Height();
+
+ // tdf#36709: TODO: Complete and consolidate unit conversion code
+ switch (rFirstLine.GetTextFirstLineOffsetUnit())
+ {
+ case css::util::MeasureUnit::FONT_IC:
+ case css::util::MeasureUnit::FONT_EM:
+ nFirstLineOfs
+ = static_cast<tools::Long>(static_cast<double>(nFntHeight)
+ * rFirstLine.GetTextFirstLineOffsetDouble());
+ break;
+
+ default:
+ nFirstLineOfs = 0;
+ break;
+ }
+ }
else
nFirstLineOfs = nFLOfst;
diff --git a/sw/source/core/unocore/unomap1.cxx b/sw/source/core/unocore/unomap1.cxx
index f9e16b1f4260..d53bdac79dfb 100644
--- a/sw/source/core/unocore/unomap1.cxx
+++ b/sw/source/core/unocore/unomap1.cxx
@@ -25,6 +25,7 @@
#include <com/sun/star/awt/Size.hpp>
#include <com/sun/star/awt/XBitmap.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/Pair.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/container/XIndexContainer.hpp>
diff --git a/sw/source/core/unocore/unomapproperties.hxx b/sw/source/core/unocore/unomapproperties.hxx
index 01cae68a6de9..2401fbc42db7 100644
--- a/sw/source/core/unocore/unomapproperties.hxx
+++ b/sw/source/core/unocore/unomapproperties.hxx
@@ -158,6 +158,7 @@
{ UNO_NAME_PARA_RIGHT_MARGIN, RES_MARGIN_RIGHT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_R_MARGIN | CONVERT_TWIPS }, \
{ UNO_NAME_PARA_IS_AUTO_FIRST_LINE_INDENT, RES_MARGIN_FIRSTLINE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_FIRST_AUTO }, \
{ UNO_NAME_PARA_FIRST_LINE_INDENT, RES_MARGIN_FIRSTLINE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_FIRST_LINE_INDENT | CONVERT_TWIPS }, \
+ { UNO_NAME_PARA_FIRST_LINE_INDENT_UNIT, RES_MARGIN_FIRSTLINE, cppu::UnoType<css::beans::Pair<double, sal_Int16>>::get(), PropertyAttribute::MAYBEVOID, MID_FIRST_LINE_UNIT_INDENT }, \
STANDARD_FONT_PROPERTIES \
CJK_FONT_PROPERTIES \
CTL_FONT_PROPERTIES \
@@ -422,6 +423,7 @@
{ UNO_NAME_PARA_RIGHT_MARGIN_RELATIVE, RES_MARGIN_RIGHT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_R_REL_MARGIN},\
{ UNO_NAME_PARA_IS_AUTO_FIRST_LINE_INDENT, RES_MARGIN_FIRSTLINE, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_FIRST_AUTO},\
{ UNO_NAME_PARA_FIRST_LINE_INDENT, RES_MARGIN_FIRSTLINE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_FIRST_LINE_INDENT|CONVERT_TWIPS},\
+ { UNO_NAME_PARA_FIRST_LINE_INDENT_UNIT, RES_MARGIN_FIRSTLINE, cppu::UnoType<css::beans::Pair<double, sal_Int16>>::get(), PROPERTY_NONE, MID_FIRST_LINE_UNIT_INDENT},\
{ UNO_NAME_PARA_FIRST_LINE_INDENT_RELATIVE, RES_MARGIN_FIRSTLINE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_FIRST_LINE_REL_INDENT|CONVERT_TWIPS},\
{ UNO_NAME_CHAR_KERNING, RES_CHRATR_KERNING , cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, CONVERT_TWIPS},\
{ UNO_NAME_CHAR_NO_HYPHENATION, RES_CHRATR_NOHYPHEN , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},\
@@ -545,6 +547,7 @@
{ UNO_NAME_PARA_ADJUST, RES_PARATR_ADJUST, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_PARA_ADJUST}, \
{ UNO_NAME_PARA_BOTTOM_MARGIN, RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_LO_MARGIN|CONVERT_TWIPS}, \
{ UNO_NAME_PARA_FIRST_LINE_INDENT, RES_MARGIN_FIRSTLINE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_FIRST_LINE_INDENT|CONVERT_TWIPS}, \
+ { UNO_NAME_PARA_FIRST_LINE_INDENT_UNIT, RES_MARGIN_FIRSTLINE, cppu::UnoType<css::beans::Pair<double, sal_Int16>>::get(), PropertyAttribute::MAYBEVOID, MID_FIRST_LINE_UNIT_INDENT}, \
{ UNO_NAME_PARA_LEFT_MARGIN, RES_MARGIN_TEXTLEFT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_TXT_LMARGIN|CONVERT_TWIPS}, \
{ UNO_NAME_PARA_LINE_SPACING, RES_PARATR_LINESPACING, cppu::UnoType<css::style::LineSpacing>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS}, \
{ UNO_NAME_PARA_RIGHT_MARGIN, RES_MARGIN_RIGHT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_R_MARGIN|CONVERT_TWIPS}, \
diff --git a/vcl/qa/cppunit/pdfexport/data/tdf36709.fodt b/vcl/qa/cppunit/pdfexport/data/tdf36709.fodt
new file mode 100644
index 000000000000..9aa29be8086b
--- /dev/null
+++ b/vcl/qa/cppunit/pdfexport/data/tdf36709.fodt
@@ -0,0 +1,151 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<office:document xmlns:css3t="http://www.w3.org/TR/css3-text/" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:rpt="http://openoffice.org/2005/report" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" office:version="1.4" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:meta><meta:creation-date>2024-10-31T13:46:50.189497642</meta:creation-date><meta:generator>LibreOfficeDev/25.2.0.0.alpha0$Linux_X86_64 LibreOffice_project/5f12ad737bbb930b76299df0433c8635ae27a7bd</meta:generator><dc:date>2024-10-31T13:49:19.200988598</dc:date><meta:editing-duration>PT2M30S</meta:editing-duration><meta:editing-cycles>1</meta:editing-cycles><meta:document-statistic meta:table-count="0" meta:image-count="0" meta:object-count="0" meta:page-count="1" meta:paragraph-count="8" meta:word-count="32" meta:character-count="144" meta:non-whitespace-character-count="120"/></office:meta>
+ <office:font-face-decls>
+ <style:font-face style:name="Liberation Serif" svg:font-family="'Liberation Serif'" style:font-family-generic="roman" style:font-pitch="variable"/>
+ <style:font-face style:name="Noto Sans1" svg:font-family="'Noto Sans'" style:font-family-generic="system" style:font-pitch="variable"/>
+ <style:font-face style:name="Noto Serif CJK SC" svg:font-family="'Noto Serif CJK SC'" style:font-family-generic="system" style:font-pitch="variable"/>
+ </office:font-face-decls>
+ <office:styles>
+ <style:default-style style:family="graphic">
+ <style:graphic-properties svg:stroke-color="#3465a4" draw:fill-color="#729fcf" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.1181in" draw:shadow-offset-y="0.1181in" draw:start-line-spacing-horizontal="0.1114in" draw:start-line-spacing-vertical="0.1114in" draw:end-line-spacing-horizontal="0.1114in" draw:end-line-spacing-vertical="0.1114in" style:flow-with-text="false"/>
+ <style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" loext:tab-stop-distance="0in" style:writing-mode="lr-tb" style:font-independent-line-spacing="false">
+ <style:tab-stops/>
+ </style:paragraph-properties>
+ <style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="en" fo:country="US" style:letter-kerning="true" style:font-name-asian="Noto Serif CJK SC" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Noto Sans1" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN"/>
+ </style:default-style>
+ <style:default-style style:family="paragraph">
+ <style:paragraph-properties fo:orphans="2" fo:widows="2" fo:hyphenation-ladder-count="no-limit" fo:hyphenation-keep="auto" loext:hyphenation-keep-type="column" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="0.4925in" style:writing-mode="page"/>
+ <style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="en" fo:country="US" style:letter-kerning="true" style:font-name-asian="Noto Serif CJK SC" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Noto Sans1" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2" loext:hyphenation-no-caps="false" loext:hyphenation-no-last-word="false" loext:hyphenation-word-char-count="5" loext:hyphenation-zone="no-limit"/>
+ </style:default-style>
+ <style:default-style style:family="table">
+ <style:table-properties table:border-model="collapsing"/>
+ </style:default-style>
+ <style:default-style style:family="table-row">
+ <style:table-row-properties fo:keep-together="auto"/>
+ </style:default-style>
+ <style:style style:name="Standard" style:family="paragraph" style:class="text"/>
+ <text:outline-style style:name="Outline">
+ <text:outline-level-style text:level="1" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="2" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="3" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="4" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="5" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="6" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="7" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="8" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="9" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="10" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ </text:outline-style>
+ <text:notes-configuration text:note-class="footnote" style:num-format="1" text:start-value="0" text:footnotes-position="page" text:start-numbering-at="document"/>
+ <text:notes-configuration text:note-class="endnote" style:num-format="i" text:start-value="0"/>
+ <text:linenumbering-configuration text:number-lines="false" text:offset="0.1965in" style:num-format="1" text:number-position="left" text:increment="5"/>
+ </office:styles>
+ <office:automatic-styles>
+ <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Standard">
+ <style:paragraph-properties loext:text-indent="0em" style:auto-text-indent="false"/>
+ <style:text-properties/>
+ </style:style>
+ <style:style style:name="P2" style:family="paragraph" style:parent-style-name="Standard">
+ <style:paragraph-properties loext:text-indent="1em" style:auto-text-indent="false"/>
+ <style:text-properties/>
+ </style:style>
+ <style:style style:name="P3" style:family="paragraph" style:parent-style-name="Standard">
+ <style:paragraph-properties loext:text-indent="2em" style:auto-text-indent="false"/>
+ <style:text-properties/>
+ </style:style>
+ <style:style style:name="P4" style:family="paragraph" style:parent-style-name="Standard">
+ <style:paragraph-properties loext:text-indent="3em" style:auto-text-indent="false"/>
+ <style:text-properties/>
+ </style:style>
+ <style:style style:name="P5" style:family="paragraph" style:parent-style-name="Standard">
+ <style:text-properties/>
+ </style:style>
+ <style:style style:name="P6" style:family="paragraph" style:parent-style-name="Standard">
+ <style:paragraph-properties loext:text-indent="2em" style:auto-text-indent="false"/>
+ <style:text-properties/>
+ </style:style>
+ <style:style style:name="P7" style:family="paragraph" style:parent-style-name="Standard">
+ <style:paragraph-properties loext:text-indent="2em" style:auto-text-indent="false"/>
+ <style:text-properties fo:font-size="16pt" style:font-size-asian="16pt" style:font-size-complex="16pt"/>
+ </style:style>
+ <style:style style:name="P8" style:family="paragraph" style:parent-style-name="Standard">
+ <style:paragraph-properties loext:text-indent="2em" style:auto-text-indent="false"/>
+ <style:text-properties fo:font-size="20pt" style:font-size-asian="20pt" style:font-size-complex="20pt"/>
+ </style:style>
+ <style:style style:name="P9" style:family="paragraph" style:parent-style-name="Standard">
+ <style:paragraph-properties loext:text-indent="2em" style:auto-text-indent="false"/>
+ <style:text-properties fo:font-size="24pt" style:font-size-asian="24pt" style:font-size-complex="24pt"/>
+ </style:style>
+ <style:page-layout style:name="pm1">
+ <style:page-layout-properties fo:page-width="8.2681in" fo:page-height="11.6929in" style:num-format="1" style:print-orientation="portrait" fo:margin-top="0.7874in" fo:margin-bottom="0.7874in" fo:margin-left="0.7874in" fo:margin-right="0.7874in" style:writing-mode="lr-tb" style:footnote-max-height="0in" loext:margin-gutter="0in">
+ <style:footnote-sep style:width="0.0071in" style:distance-before-sep="0.0398in" style:distance-after-sep="0.0398in" style:line-style="solid" style:adjustment="left" style:rel-width="25%" style:color="#000000"/>
+ </style:page-layout-properties>
+ <style:header-style/>
+ <style:footer-style/>
+ </style:page-layout>
+ </office:automatic-styles>
+ <office:master-styles>
+ <style:master-page style:name="Standard" style:page-layout-name="pm1"/>
+ </office:master-styles>
+ <office:body>
+ <office:text>
+ <text:sequence-decls>
+ <text:sequence-decl text:display-outline-level="0" text:name="Illustration"/>
+ <text:sequence-decl text:display-outline-level="0" text:name="Table"/>
+ <text:sequence-decl text:display-outline-level="0" text:name="Text"/>
+ <text:sequence-decl text:display-outline-level="0" text:name="Drawing"/>
+ <text:sequence-decl text:display-outline-level="0" text:name="Figure"/>
+ </text:sequence-decls>
+ <text:p text:style-name="P1">0 em constant size</text:p>
+ <text:p text:style-name="P2">1 em constant size</text:p>
+ <text:p text:style-name="P3">2 em constant size</text:p>
+ <text:p text:style-name="P4">3 em constant size</text:p>
+ <text:p text:style-name="P5"/>
+ <text:p text:style-name="P6">2 em variable size</text:p>
+ <text:p text:style-name="P7">2 em variable size</text:p>
+ <text:p text:style-name="P8">2 em variable size</text:p>
+ <text:p text:style-name="P9">2 em variable size</text:p>
+ </office:text>
+ </office:body>
+</office:document> \ No newline at end of file
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport2.cxx b/vcl/qa/cppunit/pdfexport/pdfexport2.cxx
index 9a1a314ad3e7..72b2038b7d73 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport2.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport2.cxx
@@ -5822,6 +5822,57 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest2, testTdf140767SyriacJustification)
CPPUNIT_ASSERT_LESS(90.0, aRect.at(5).getWidth());
}
+CPPUNIT_TEST_FIXTURE(PdfExportTest2, testTdf36709FirstLineIndentEm)
+{
+ saveAsPDF(u"tdf36709.fodt");
+
+ auto pPdfDocument = parsePDFExport();
+ CPPUNIT_ASSERT_EQUAL(1, pPdfDocument->getPageCount());
+
+ auto pPdfPage = pPdfDocument->openPage(/*nIndex*/ 0);
+ CPPUNIT_ASSERT(pPdfPage);
+ auto pTextPage = pPdfPage->getTextPage();
+ CPPUNIT_ASSERT(pTextPage);
+
+ int nPageObjectCount = pPdfPage->getObjectCount();
+
+ CPPUNIT_ASSERT_EQUAL(8, nPageObjectCount);
+
+ std::vector<OUString> aText;
+ std::vector<basegfx::B2DRectangle> aRect;
+
+ for (int i = 0; i < nPageObjectCount; ++i)
+ {
+ auto pPageObject = pPdfPage->getObject(i);
+ CPPUNIT_ASSERT_MESSAGE("no object", pPageObject != nullptr);
+ if (pPageObject->getType() == vcl::pdf::PDFPageObjectType::Text)
+ {
+ aText.push_back(pPageObject->getText(pTextPage));
+ aRect.push_back(pPageObject->getBounds());
+ }
+ }
+
+ CPPUNIT_ASSERT_EQUAL(size_t(8), aText.size());
+
+ CPPUNIT_ASSERT_EQUAL(u"0 em constant size"_ustr, aText.at(0).trim());
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(57.256, aRect.at(0).getMinX(), /*delta*/ 2.0);
+ CPPUNIT_ASSERT_EQUAL(u"1 em constant size"_ustr, aText.at(1).trim());
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(69.856, aRect.at(1).getMinX(), /*delta*/ 2.0);
+ CPPUNIT_ASSERT_EQUAL(u"2 em constant size"_ustr, aText.at(2).trim());
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(81.328, aRect.at(2).getMinX(), /*delta*/ 2.0);
+ CPPUNIT_ASSERT_EQUAL(u"3 em constant size"_ustr, aText.at(3).trim());
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(93.376, aRect.at(3).getMinX(), /*delta*/ 2.0);
+
+ CPPUNIT_ASSERT_EQUAL(u"2 em variable size"_ustr, aText.at(4).trim());
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(81.328, aRect.at(4).getMinX(), /*delta*/ 2.0);
+ CPPUNIT_ASSERT_EQUAL(u"2 em variable size"_ustr, aText.at(5).trim());
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(89.504, aRect.at(5).getMinX(), /*delta*/ 2.0);
+ CPPUNIT_ASSERT_EQUAL(u"2 em variable size"_ustr, aText.at(6).trim());
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(97.680, aRect.at(6).getMinX(), /*delta*/ 2.0);
+ CPPUNIT_ASSERT_EQUAL(u"2 em variable size"_ustr, aText.at(7).trim());
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(105.856, aRect.at(7).getMinX(), /*delta*/ 2.0);
+}
+
} // end anonymous namespace
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/xmloff/inc/xmlbahdl.hxx b/xmloff/inc/xmlbahdl.hxx
index 09e392d6cc6b..7736d6d2f432 100644
--- a/xmloff/inc/xmlbahdl.hxx
+++ b/xmloff/inc/xmlbahdl.hxx
@@ -69,6 +69,16 @@ public:
};
/**
+ PropertyHandler for the XML-data-type: XML_TYPE_UNIT_MEASURE
+*/
+class XMLUnitMeasurePropHdl : public XMLPropertyHandler
+{
+public:
+ bool importXML( const OUString& rStrImpValue, css::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const override;
+ bool exportXML( OUString& rStrExpValue, const css::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const override;
+};
+
+/**
PropertyHandler for the XML-data-type: XML_TYPE_PERCENT
*/
class XMLPercentPropHdl : public XMLPropertyHandler
diff --git a/xmloff/inc/xmlprop.hxx b/xmloff/inc/xmlprop.hxx
index b7acca175a1d..8f47e328ff44 100644
--- a/xmloff/inc/xmlprop.hxx
+++ b/xmloff/inc/xmlprop.hxx
@@ -489,6 +489,7 @@ inline constexpr OUString PROP_ParaContextMargin = u"ParaContextMargin"_ustr;
inline constexpr OUString PROP_ParaExpandSingleWord = u"ParaExpandSingleWord"_ustr;
inline constexpr OUString PROP_ParaFirstLineIndent = u"ParaFirstLineIndent"_ustr;
inline constexpr OUString PROP_ParaFirstLineIndentRelative = u"ParaFirstLineIndentRelative"_ustr;
+inline constexpr OUString PROP_ParaFirstLineIndentUnit = u"ParaFirstLineIndentUnit"_ustr;
inline constexpr OUString PROP_ParaHyphenationMaxHyphens = u"ParaHyphenationMaxHyphens"_ustr;
inline constexpr OUString PROP_ParaHyphenationMaxLeadingChars
= u"ParaHyphenationMaxLeadingChars"_ustr;
diff --git a/xmloff/source/style/prhdlfac.cxx b/xmloff/source/style/prhdlfac.cxx
index a14d61ea31c2..fd6dae604bf8 100644
--- a/xmloff/source/style/prhdlfac.cxx
+++ b/xmloff/source/style/prhdlfac.cxx
@@ -195,6 +195,9 @@ std::unique_ptr<XMLPropertyHandler> XMLPropertyHandlerFactory::CreatePropertyHan
case XML_TYPE_MEASURE16:
pPropHdl.reset(new XMLMeasurePropHdl( 2 ));
break;
+ case XML_TYPE_UNIT_MEASURE:
+ pPropHdl = std::make_unique<XMLUnitMeasurePropHdl>();
+ break;
case XML_TYPE_PERCENT :
pPropHdl.reset(new XMLPercentPropHdl( 4 ));
break;
diff --git a/xmloff/source/style/xmlbahdl.cxx b/xmloff/source/style/xmlbahdl.cxx
index a0aea8ccb1a4..02c271ad6a2e 100644
--- a/xmloff/source/style/xmlbahdl.cxx
+++ b/xmloff/source/style/xmlbahdl.cxx
@@ -27,6 +27,7 @@
#include <sax/tools/converter.hxx>
#include <xmloff/xmluconv.hxx>
#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/beans/Pair.hpp>
#include <xmloff/xmltoken.hxx>
#include <limits.h>
@@ -207,6 +208,58 @@ bool XMLMeasurePropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, co
}
+bool XMLUnitMeasurePropHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& ) const
+{
+ double fValue = 0.0;
+ std::optional<sal_Int16> nValueUnit;
+
+ auto bRet = ::sax::Converter::convertMeasureUnit( fValue, nValueUnit, rStrImpValue );
+
+ if(bRet)
+ {
+ // This importer may only accept font-relative units.
+ // Discard all other units to allow fall-through to other attributes.
+ if (css::util::MeasureUnit::FONT_EM != nValueUnit
+ && css::util::MeasureUnit::FONT_IC != nValueUnit)
+ {
+ return false;
+ }
+
+ css::beans::Pair<double, sal_Int16> stValue{fValue, nValueUnit.value()};
+ rValue <<= stValue;
+ }
+
+ return bRet;
+}
+
+bool XMLUnitMeasurePropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
+{
+ bool bRet = false;
+ css::beans::Pair<double, sal_Int16> stValue{0.0, css::util::MeasureUnit::MM_100TH};
+
+ if( rValue >>= stValue )
+ {
+ auto [fValue, nValueUnit] = stValue;
+
+ // This exporter may only produce font-relative units.
+ // Discard all other units to allow fall-through to other attributes.
+ if (css::util::MeasureUnit::FONT_EM != nValueUnit
+ && css::util::MeasureUnit::FONT_IC != nValueUnit)
+ {
+ return false;
+ }
+
+ OUStringBuffer aOut;
+ ::sax::Converter::convertMeasureUnit( aOut, fValue, nValueUnit );
+ rStrExpValue = aOut.makeStringAndClear();
+
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+
XMLBoolFalsePropHdl::~XMLBoolFalsePropHdl()
{
// nothing to do
diff --git a/xmloff/source/text/txtprmap.cxx b/xmloff/source/text/txtprmap.cxx
index 25cb36ef1b0d..8553965c67d0 100644
--- a/xmloff/source/text/txtprmap.cxx
+++ b/xmloff/source/text/txtprmap.cxx
@@ -366,6 +366,9 @@ XMLPropertyMapEntry constexpr aXMLParaPropMap[] =
MP_E( PROP_ParaFirstLineIndent, XML_NAMESPACE_FO, XML_TEXT_INDENT, XML_TYPE_MEASURE|MID_FLAG_MULTI_PROPERTY, CTF_PARAFIRSTLINE ),
MP_E( PROP_ParaFirstLineIndentRelative, XML_NAMESPACE_FO, XML_TEXT_INDENT, XML_TYPE_PERCENT, CTF_PARAFIRSTLINE_REL ),
+ MAP_EXT( PROP_ParaFirstLineIndentUnit, XML_NAMESPACE_LO_EXT, XML_TEXT_INDENT, XML_TYPE_PROP_PARAGRAPH|XML_TYPE_UNIT_MEASURE|MID_FLAG_MULTI_PROPERTY, 0 ),
+ MAP_EXT_I( PROP_ParaFirstLineIndent, XML_NAMESPACE_LO_EXT, XML_TEXT_INDENT, XML_TYPE_PROP_PARAGRAPH|XML_TYPE_MEASURE|MID_FLAG_MULTI_PROPERTY, CTF_PARAFIRSTLINE ),
+ MAP_EXT_I( PROP_ParaFirstLineIndentRelative, XML_NAMESPACE_LO_EXT, XML_TEXT_INDENT, XML_TYPE_PROP_PARAGRAPH|XML_TYPE_PERCENT, CTF_PARAFIRSTLINE_REL ),
MP_E( PROP_ParaIsAutoFirstLineIndent, XML_NAMESPACE_STYLE, XML_AUTO_TEXT_INDENT, XML_TYPE_BOOL, 0 ),
// RES_PAGEDESC
MP_E( PROP_PageDescName, XML_NAMESPACE_STYLE, XML_MASTER_PAGE_NAME, MID_FLAG_SPECIAL_ITEM|XML_TYPE_STYLENAME, CTF_PAGEDESCNAME ),