tdf#149420 sw offapi xmloff: add hyphenation zone
Add hyphenation zone support, i.e. allow the specified
amount of extra space in lines instead of forcing hyphenation.
It's for limiting hyphenation, used especially with
not justified paragraph alignment.
Note: this is an OOXML interoperability feature,
used also in DTP software and CSS.
* Add checkbox to Text Flow in paragraph dialog
* Store property in paragraph model (com::sun::star::style::ParagraphProperties::ParaHyphenationZone)
* Add ODF import/export
* Add ODF unit test
* Add layout test
Note: extend SvxHyphenZoneItem::GetPresentation() with
missing No CAPS and No last word hyphenation options.
Note: fix OSL_ENSURE condition in SwTextFormatInfo::GetHyphValues().
Follow-up to commit 29359fc15c435cec17987fd6221ab6833d38746e
"tdf#149324 sw offapi xmloff: add option to not hyphenate short words".
Change-Id: Ib8eff6ea98a9aa5ca6cb9d17faa0bbb789687ce9
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135247
Tested-by: Jenkins
Reviewed-by: László Németh <nemeth@numbertext.org>
diff --git a/cui/source/inc/paragrph.hxx b/cui/source/inc/paragrph.hxx
index f0c5677..3947c14 100644
--- a/cui/source/inc/paragrph.hxx
+++ b/cui/source/inc/paragrph.hxx
@@ -233,6 +233,7 @@ private:
std::unique_ptr<weld::Label> m_xMaxHyphenLabel;
std::unique_ptr<weld::SpinButton> m_xMaxHyphenEdit;
std::unique_ptr<weld::SpinButton> m_xMinWordLength;
std::unique_ptr<SvxRelativeField> m_xHyphenZone;
// pagebreak
std::unique_ptr<weld::CheckButton> m_xPageBreakBox;
diff --git a/cui/source/tabpages/paragrph.cxx b/cui/source/tabpages/paragrph.cxx
index 2d651fe..3fa77d9 100644
--- a/cui/source/tabpages/paragrph.cxx
+++ b/cui/source/tabpages/paragrph.cxx
@@ -1356,7 +1356,8 @@ bool SvxExtParagraphTabPage::FillItemSet( SfxItemSet* rOutSet )
m_xExtHyphenBeforeBox->get_value_changed_from_saved() ||
m_xExtHyphenAfterBox->get_value_changed_from_saved() ||
m_xMaxHyphenEdit->get_value_changed_from_saved() ||
m_xMinWordLength->get_value_changed_from_saved() )
m_xMinWordLength->get_value_changed_from_saved() ||
m_xHyphenZone->get_value_changed_from_saved() )
{
SvxHyphenZoneItem aHyphen(
static_cast<const SvxHyphenZoneItem&>(GetItemSet().Get( _nWhich )) );
@@ -1372,6 +1373,11 @@ bool SvxExtParagraphTabPage::FillItemSet( SfxItemSet* rOutSet )
}
aHyphen.GetMaxHyphens() = static_cast<sal_uInt8>(m_xMaxHyphenEdit->get_value());
SfxItemPool* pPool = GetItemSet().GetPool();
DBG_ASSERT( pPool, "Where is the pool?" );
MapUnit eUnit = pPool->GetMetric( _nWhich );
aHyphen.GetTextHyphenZone() = static_cast<sal_uInt16>(m_xHyphenZone->GetCoreValue(eUnit));
if ( !pOld ||
*static_cast<const SvxHyphenZoneItem*>(pOld) != aHyphen ||
m_xHyphenBox->get_state_changed_from_saved())
@@ -1560,6 +1566,17 @@ bool SvxExtParagraphTabPage::FillItemSet( SfxItemSet* rOutSet )
}
void SvxExtParagraphTabPage::Reset( const SfxItemSet* rSet )
{
SfxItemPool* pPool = rSet->GetPool();
DBG_ASSERT( pPool, "Where is the pool?" );
// adjust metric
FieldUnit eFUnit = GetModuleFieldUnit( *rSet );
bool bApplyCharUnit = GetApplyCharUnit( *rSet );
if( SvtCJKOptions::IsAsianTypographyEnabled() && bApplyCharUnit )
eFUnit = FieldUnit::CHAR;
sal_uInt16 _nWhich = GetWhich( SID_ATTR_PARA_HYPHENZONE );
SfxItemState eItemState = rSet->GetItemState( _nWhich );
@@ -1580,6 +1597,8 @@ void SvxExtParagraphTabPage::Reset( const SfxItemSet* rSet )
m_xExtHyphenAfterBox->set_value(rHyphen.GetMinTrail());
m_xMaxHyphenEdit->set_value(rHyphen.GetMaxHyphens());
m_xMinWordLength->set_value(rHyphen.GetMinWordLength());
m_xHyphenZone->SetFieldUnit(eFUnit);
m_xHyphenZone->SetMetricValue(rHyphen.GetTextHyphenZone(), MapUnit::MapTwip);
}
else
{
@@ -1597,6 +1616,7 @@ void SvxExtParagraphTabPage::Reset( const SfxItemSet* rSet )
m_xMaxHyphenLabel->set_sensitive(bEnable);
m_xMaxHyphenEdit->set_sensitive(bEnable);
m_xMinWordLength->set_sensitive(bEnable);
m_xHyphenZone->set_sensitive(bEnable);
switch (rSet->GetItemState(SID_ATTR_PARA_PAGENUM))
{
@@ -1857,6 +1877,11 @@ void SvxExtParagraphTabPage::ChangesApplied()
m_xExtHyphenAfterBox->set_value(m_xExtHyphenAfterBox->get_value());
m_xMaxHyphenEdit->set_value(m_xMaxHyphenEdit->get_value());
m_xMinWordLength->set_value(m_xMinWordLength->get_value());
SfxItemPool* pPool = GetItemSet().GetPool();
DBG_ASSERT( pPool, "Where is the pool?" );
FieldUnit eUnit =
MapToFieldUnit( pPool->GetMetric( GetWhich( SID_ATTR_PARA_HYPHENZONE ) ) );
m_xHyphenZone->set_value(m_xHyphenZone->get_value(eUnit), eUnit);
m_xPageBreakBox->save_state();
m_xBreakPositionLB->save_value();
m_xBreakTypeLB->save_value();
@@ -1908,6 +1933,7 @@ SvxExtParagraphTabPage::SvxExtParagraphTabPage(weld::Container* pPage, weld::Dia
, m_xMaxHyphenLabel(m_xBuilder->weld_label("labelMaxNum"))
, m_xMaxHyphenEdit(m_xBuilder->weld_spin_button("spinMaxNum"))
, m_xMinWordLength(m_xBuilder->weld_spin_button("spinMinLen"))
, m_xHyphenZone(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("spinHyphenZone", FieldUnit::CM)))
//Page break
, m_xPageBreakBox(m_xBuilder->weld_check_button("checkInsert"))
, m_xBreakTypeFT(m_xBuilder->weld_label("labelType"))
diff --git a/cui/uiconfig/ui/textflowpage.ui b/cui/uiconfig/ui/textflowpage.ui
index 89ac8a3..496f22f 100644
--- a/cui/uiconfig/ui/textflowpage.ui
+++ b/cui/uiconfig/ui/textflowpage.ui
@@ -48,6 +48,11 @@
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkAdjustment" id="adjustment8">
<property name="upper">55.88</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<!-- n-columns=1 n-rows=1 -->
<object class="GtkGrid" id="TextFlowPage">
<property name="visible">True</property>
@@ -258,6 +263,49 @@
<property name="width">2</property>
</packing>
</child>
<child>
<!-- n-columns=1 n-rows=1 -->
<object class="GtkGrid" id="gridHyphenZone">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<property name="margin-start">12</property>
<property name="margin-top">6</property>
<child>
<object class="GtkSpinButton" id="spinHyphenZone">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="activates_default">True</property>
<property name="truncate_multiline">True</property>
<property name="adjustment">adjustment8</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="labelHyphenZone">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes" context="textflowpage|labelHyphenZone">Hyphenation _zone:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">spinHyphenZone</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">7</property>
<property name="width">2</property>
</packing>
</child>
</object>
</child>
<child type="label">
diff --git a/editeng/source/items/paraitem.cxx b/editeng/source/items/paraitem.cxx
index 202341ca..9368dfd 100644
--- a/editeng/source/items/paraitem.cxx
+++ b/editeng/source/items/paraitem.cxx
@@ -559,7 +559,8 @@ SvxHyphenZoneItem::SvxHyphenZoneItem( const bool bHyph, const sal_uInt16 nId ) :
nMinLead(0),
nMinTrail(0),
nMaxHyphens(255),
nMinWordLength(0)
nMinWordLength(0),
nTextHyphenZone(0)
{
}
@@ -590,6 +591,9 @@ bool SvxHyphenZoneItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) con
case MID_HYPHEN_MIN_WORD_LENGTH:
rVal <<= static_cast<sal_Int16>(nMinWordLength);
break;
case MID_HYPHEN_ZONE:
rVal <<= static_cast<sal_Int16>(nTextHyphenZone);
break;
}
return true;
}
@@ -629,6 +633,9 @@ bool SvxHyphenZoneItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
case MID_HYPHEN_MIN_WORD_LENGTH:
nMinWordLength = static_cast<sal_uInt8>(nNewVal);
break;
case MID_HYPHEN_ZONE:
nTextHyphenZone = nNewVal;
break;
}
return true;
}
@@ -646,7 +653,8 @@ bool SvxHyphenZoneItem::operator==( const SfxPoolItem& rAttr ) const
&& rItem.nMinLead == nMinLead
&& rItem.nMinTrail == nMinTrail
&& rItem.nMaxHyphens == nMaxHyphens
&& rItem.nMinWordLength == nMinWordLength );
&& rItem.nMinWordLength == nMinWordLength
&& rItem.nTextHyphenZone == nTextHyphenZone );
}
SvxHyphenZoneItem* SvxHyphenZoneItem::Clone( SfxItemPool * ) const
@@ -657,9 +665,9 @@ SvxHyphenZoneItem* SvxHyphenZoneItem::Clone( SfxItemPool * ) const
bool SvxHyphenZoneItem::GetPresentation
(
SfxItemPresentation ePres,
MapUnit /*eCoreUnit*/,
MapUnit /*ePresUnit*/,
OUString& rText, const IntlWrapper&
MapUnit eCoreUnit,
MapUnit ePresUnit,
OUString& rText, const IntlWrapper& rIntl
) const
{
OUString cpDelimTmp(cpDelim);
@@ -680,7 +688,16 @@ bool SvxHyphenZoneItem::GetPresentation
OUString::number( nMinLead ) + cpDelimTmp +
OUString::number( nMinTrail ) + cpDelimTmp +
OUString::number( nMaxHyphens ) + cpDelimTmp +
OUString::number( nMinWordLength );
OUString::number( nMinWordLength ) + cpDelimTmp +
GetMetricText( nTextHyphenZone, eCoreUnit, ePresUnit, &rIntl ) +
" " + EditResId(GetMetricId(ePresUnit));
if ( bNoCapsHyphenation )
rText += cpDelimTmp + EditResId(RID_SVXITEMS_HYPHEN_NO_CAPS_TRUE);
if ( bNoLastWordHyphenation )
rText += cpDelimTmp + EditResId(RID_SVXITEMS_HYPHEN_LAST_WORD_TRUE);
return true;
}
case SfxItemPresentation::Complete:
@@ -703,6 +720,20 @@ bool SvxHyphenZoneItem::GetPresentation
EditResId(RID_SVXITEMS_HYPHEN_MAX).replaceAll("%1", OUString::number(nMaxHyphens)) +
cpDelimTmp +
EditResId(RID_SVXITEMS_HYPHEN_MINWORDLEN).replaceAll("%1", OUString::number(nMinWordLength));
if ( nTextHyphenZone > 0 )
{
rText += cpDelimTmp + EditResId(RID_SVXITEMS_HYPHEN_ZONE) +
GetMetricText( nTextHyphenZone, eCoreUnit, ePresUnit, &rIntl ) +
" " + EditResId(GetMetricId(ePresUnit));
}
if ( bNoCapsHyphenation )
rText += cpDelimTmp + EditResId(RID_SVXITEMS_HYPHEN_NO_CAPS_TRUE);
if ( bNoLastWordHyphenation )
rText += cpDelimTmp + EditResId(RID_SVXITEMS_HYPHEN_LAST_WORD_TRUE);
return true;
}
default: ;//prevent warning
diff --git a/include/editeng/editrids.hrc b/include/editeng/editrids.hrc
index 57342e7..31ac07a 100644
--- a/include/editeng/editrids.hrc
+++ b/include/editeng/editrids.hrc
@@ -230,7 +230,10 @@
#define RID_SVXITEMS_HYPHEN_MINLEAD NC_("RID_SVXITEMS_HYPHEN_MINLEAD", "%1 characters at end of line")
#define RID_SVXITEMS_HYPHEN_MINTRAIL NC_("RID_SVXITEMS_HYPHEN_MINTRAIL", "%1 characters at beginning of line")
#define RID_SVXITEMS_HYPHEN_MAX NC_("RID_SVXITEMS_HYPHEN_MAX", "%1 hyphens")
#define RID_SVXITEMS_HYPHEN_MINWORDLEN NC_("RID_SVXITEMS_HYPHEN_MINWORDLEN", "Words with at least %1 characters")
#define RID_SVXITEMS_HYPHEN_NO_CAPS_TRUE NC_("RID_SVXITEMS_HYPHEN_NO_CAPS_TRUE", "Not hyphenated CAPS")
#define RID_SVXITEMS_HYPHEN_LAST_WORD_TRUE NC_("RID_SVXITEMS_HYPHEN_NO_CAPS_FALSE", "Not hyphenated last word")
#define RID_SVXITEMS_HYPHEN_MINWORDLEN NC_("RID_SVXITEMS_HYPHEN_MINWORDLEN", "%1 characters in words")
#define RID_SVXITEMS_HYPHEN_ZONE NC_("RID_SVXITEMS_HYPHEN_ZONE", "Hyphenation zone ")
#define RID_SVXITEMS_PAGEMODEL_COMPLETE NC_("RID_SVXITEMS_PAGEMODEL_COMPLETE", "Page Style: ")
#define RID_SVXITEMS_KERNING_COMPLETE NC_("RID_SVXITEMS_KERNING_COMPLETE", "Kerning ")
#define RID_SVXITEMS_KERNING_EXPANDED NC_("RID_SVXITEMS_KERNING_EXPANDED", "locked ")
diff --git a/include/editeng/hyphenzoneitem.hxx b/include/editeng/hyphenzoneitem.hxx
index b1ec7cb..7104d2d 100644
--- a/include/editeng/hyphenzoneitem.hxx
+++ b/include/editeng/hyphenzoneitem.hxx
@@ -38,8 +38,9 @@ class EDITENG_DLLPUBLIC SvxHyphenZoneItem final : public SfxPoolItem
bool bNoLastWordHyphenation : 1;
sal_uInt8 nMinLead;
sal_uInt8 nMinTrail;
sal_uInt8 nMaxHyphens;
sal_uInt8 nMinWordLength;
sal_uInt8 nMaxHyphens; // max. consecutive lines with hyphenation
sal_uInt8 nMinWordLength; // hyphenate only words with at least nMinWordLength characters
sal_uInt16 nTextHyphenZone; // don't force hyphenation at line end, allow this extra white space
public:
static SfxPoolItem* CreateDefault();
@@ -81,6 +82,9 @@ public:
sal_uInt8 &GetMinWordLength() { return nMinWordLength; }
sal_uInt8 GetMinWordLength() const { return nMinWordLength; }
sal_uInt16 &GetTextHyphenZone() { return nTextHyphenZone; }
sal_uInt16 GetTextHyphenZone() const { return nTextHyphenZone; }
};
#endif
diff --git a/include/editeng/memberids.h b/include/editeng/memberids.h
index 4ec470f3..9b89eba 100644
--- a/include/editeng/memberids.h
+++ b/include/editeng/memberids.h
@@ -49,6 +49,7 @@
#define MID_HYPHEN_NO_CAPS 4
#define MID_HYPHEN_NO_LAST_WORD 5
#define MID_HYPHEN_MIN_WORD_LENGTH 6
#define MID_HYPHEN_ZONE 7
// SvxBoxInfoItem
#define MID_HORIZONTAL 1
diff --git a/include/unotools/linguprops.hxx b/include/unotools/linguprops.hxx
index adede0b..971c028 100644
--- a/include/unotools/linguprops.hxx
+++ b/include/unotools/linguprops.hxx
@@ -42,6 +42,7 @@ inline constexpr OUStringLiteral UPN_HYPH_MIN_TRAILING = u"HyphMin
inline constexpr OUStringLiteral UPN_HYPH_MIN_WORD_LENGTH = u"HyphMinWordLength";
inline constexpr OUStringLiteral UPN_HYPH_NO_CAPS = u"HyphNoCaps";
inline constexpr OUStringLiteral UPN_HYPH_NO_LAST_WORD = u"HyphNoLastWord";
inline constexpr OUStringLiteral UPN_HYPH_ZONE = u"HyphZone";
// UNO property names for Lingu
// (those not covered by the SpellChecker and Hyphenator
@@ -109,6 +110,7 @@ inline constexpr OUStringLiteral UPN_IS_GRAMMAR_INTERACTIVE = u"IsInter
#define UPH_IS_GRAMMAR_INTERACTIVE 35
#define UPH_HYPH_NO_CAPS 36
#define UPH_HYPH_NO_LAST_WORD 37
#define UPH_HYPH_ZONE 38
#ifdef __GNUC__
#pragma GCC diagnostic pop
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index 4592c01..69a4956 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -1053,6 +1053,7 @@ namespace xmloff::token {
XML_HYPHENATION_NO_CAPS,
XML_HYPHENATION_NO_LAST_WORD,
XML_HYPHENATION_WORD_CHAR_COUNT,
XML_HYPHENATION_ZONE,
XML_I,
XML_ICON,
XML_ICON_SET,
diff --git a/offapi/com/sun/star/style/ParagraphProperties.idl b/offapi/com/sun/star/style/ParagraphProperties.idl
index e9522d77..32a6328 100644
--- a/offapi/com/sun/star/style/ParagraphProperties.idl
+++ b/offapi/com/sun/star/style/ParagraphProperties.idl
@@ -428,6 +428,13 @@ published service ParagraphProperties
@since LibreOffice 7.4
*/
[optional, property] short ParaHyphenationMinWordLength;
/** specifies the hyphenation zone, i.e. allowed extra white space
in the line before applying hyphenation.
@since LibreOffice 7.4
*/
[optional, property] long ParaHyphenationZone;
};
diff --git a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
index d5857c1..293e40d 100644
--- a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
+++ b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
@@ -2727,6 +2727,18 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
</rng:define>
<!-- TODO no proposal -->
<rng:define name="style-text-properties-attlist" combine="interleave">
<rng:optional>
<rng:attribute name="loext:hyphenation-zone">
<rng:choice>
<rng:value>no-limit</rng:value>
<rng:ref name="positiveInteger"/>
</rng:choice>
</rng:attribute>
</rng:optional>
</rng:define>
<!-- TODO no proposal -->
<rng:define name="chart-data-point-attlist" combine="interleave">
<rng:optional>
<rng:attribute name="loext:custom-label-pos-x">
diff --git a/svx/sdi/svxitems.sdi b/svx/sdi/svxitems.sdi
index 00e4b74..df38999 100644
--- a/svx/sdi/svxitems.sdi
+++ b/svx/sdi/svxitems.sdi
@@ -260,6 +260,7 @@ struct SvxHyphenZone
INT16 MinTrail MID_HYPHEN_MIN_TRAIL;
INT16 MaxHyphens MID_HYPHEN_MAX_HYPHENS;
INT16 MinWordLength MID_HYPHEN_MIN_WORD_LENGTH;
INT16 HyphenZone MID_HYPHEN_ZONE;
};
item SvxHyphenZone SvxHyphenZoneItem;
diff --git a/sw/inc/inspectorproperties.hrc b/sw/inc/inspectorproperties.hrc
index f1327ec..c2fd2a1 100644
--- a/sw/inc/inspectorproperties.hrc
+++ b/sw/inc/inspectorproperties.hrc
@@ -208,6 +208,7 @@
#define RID_PARA_HYPHENATION_NO_CAPS NC_("RID_ATTRIBUTE_NAMES_MAP", "Para Hyphenation No Caps")
#define RID_PARA_HYPHENATION_NO_LAST_WORD NC_("RID_ATTRIBUTE_NAMES_MAP", "Para Hyphenation No Last Word")
#define RID_PARA_HYPHENATION_MIN_WORD_LENGTH NC_("RID_ATTRIBUTE_NAMES_MAP", "Para Hyphenation Min Word Length")
#define RID_PARA_HYPHENATION_ZONE NC_("RID_ATTRIBUTE_NAMES_MAP", "Para Hyphenation Zone")
#define RID_PARA_INTEROP_GRAB_BAG NC_("RID_ATTRIBUTE_NAMES_MAP", "Para Interop Grab Bag")
#define RID_PARA_IS_AUTO_FIRST_LINE_INDENT NC_("RID_ATTRIBUTE_NAMES_MAP", "Para is Auto First Line Indent")
#define RID_PARA_IS_CHARACTER_DISTANCE NC_("RID_ATTRIBUTE_NAMES_MAP", "Para is Character Distance")
diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx
index 14da263..c3a7d97 100644
--- a/sw/inc/unoprnms.hxx
+++ b/sw/inc/unoprnms.hxx
@@ -65,6 +65,7 @@
#define UNO_NAME_PARA_HYPHENATION_MAX_TRAILING_CHARS "ParaHyphenationMaxTrailingChars"
#define UNO_NAME_PARA_HYPHENATION_MAX_HYPHENS "ParaHyphenationMaxHyphens"
#define UNO_NAME_PARA_HYPHENATION_MIN_WORD_LENGTH "ParaHyphenationMinWordLength"
#define UNO_NAME_PARA_HYPHENATION_ZONE "ParaHyphenationZone"
#define UNO_NAME_PARA_HYPHENATION_NO_CAPS "ParaHyphenationNoCaps"
#define UNO_NAME_PARA_HYPHENATION_NO_LAST_WORD "ParaHyphenationNoLastWord"
#define UNO_NAME_LEFT_MARGIN "LeftMargin"
diff --git a/sw/qa/extras/layout/data/tdf149420.odt b/sw/qa/extras/layout/data/tdf149420.odt
new file mode 100644
index 0000000..249d726
--- /dev/null
+++ b/sw/qa/extras/layout/data/tdf149420.odt
Binary files differ
diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx
index e42f5c2..2a6b2ca 100644
--- a/sw/qa/extras/layout/layout.cxx
+++ b/sw/qa/extras/layout/layout.cxx
@@ -4379,6 +4379,21 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf121658)
assertXPath(pXmlDoc, "//Special[@nType='PortionType::Hyphen']", 2);
}
CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf149420)
{
uno::Reference<linguistic2::XHyphenator> xHyphenator = LinguMgr::GetHyphenator();
if (!xHyphenator->hasLocale(lang::Locale("en", "US", OUString())))
return;
createSwDoc(DATA_DIRECTORY, "tdf149420.odt");
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
// Only 3 hyphenated words should appear in the document (last paragraph
// has got a 1 cm hyphenation zone, removing two hyphenations, which visible
// in the second paragraph).
assertXPath(pXmlDoc, "//Special[@nType='PortionType::Hyphen']", 8);
}
CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf149324)
{
uno::Reference<linguistic2::XHyphenator> xHyphenator = LinguMgr::GetHyphenator();
diff --git a/sw/qa/extras/odfexport/data/tdf149420.odt b/sw/qa/extras/odfexport/data/tdf149420.odt
new file mode 100644
index 0000000..249d726
--- /dev/null
+++ b/sw/qa/extras/odfexport/data/tdf149420.odt
Binary files differ
diff --git a/sw/qa/extras/odfexport/odfexport.cxx b/sw/qa/extras/odfexport/odfexport.cxx
index 6f85db1..e58b772 100644
--- a/sw/qa/extras/odfexport/odfexport.cxx
+++ b/sw/qa/extras/odfexport/odfexport.cxx
@@ -3052,6 +3052,13 @@ DECLARE_ODFEXPORT_TEST(tdf149324, "tdf149324.odt")
CPPUNIT_ASSERT_EQUAL(sal_uInt16(7), getProperty<sal_uInt16>(getParagraph(4), "ParaHyphenationMinWordLength"));
}
DECLARE_ODFEXPORT_TEST(tdf149420, "tdf149420.odt")
{
CPPUNIT_ASSERT_EQUAL(1, getPages());
CPPUNIT_ASSERT_EQUAL(sal_uInt16(0), getProperty<sal_uInt16>(getParagraph(2), "ParaHyphenationZone"));
CPPUNIT_ASSERT_EQUAL(sal_uInt16(567), getProperty<sal_uInt16>(getParagraph(4), "ParaHyphenationZone"));
}
DECLARE_ODFEXPORT_TEST(testArabicZeroNumbering, "arabic-zero-numbering.odt")
{
CPPUNIT_ASSERT_EQUAL(1, getPages());
diff --git a/sw/qa/uitest/styleInspector/styleInspector.py b/sw/qa/uitest/styleInspector/styleInspector.py
index 29300f6..f5ce2cd 100644
--- a/sw/qa/uitest/styleInspector/styleInspector.py
+++ b/sw/qa/uitest/styleInspector/styleInspector.py
@@ -26,7 +26,7 @@ class styleNavigator(UITestCase):
# The cursor is on text without formatting and default style
self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
self.assertEqual(139, len(xListBox.getChild('0').getChild('0').getChildren()))
self.assertEqual(140, len(xListBox.getChild('0').getChild('0').getChildren()))
self.assertEqual(0, len(xListBox.getChild('1').getChildren()))
self.assertEqual(0, len(xListBox.getChild('2').getChildren()))
self.assertEqual(0, len(xListBox.getChild('3').getChildren()))
@@ -36,7 +36,7 @@ class styleNavigator(UITestCase):
# The cursor is on text with direct formatting
self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
self.assertEqual(139, len(xListBox.getChild('0').getChild('0').getChildren()))
self.assertEqual(140, len(xListBox.getChild('0').getChild('0').getChildren()))
self.assertEqual(0, len(xListBox.getChild('1').getChildren()))
self.assertEqual(0, len(xListBox.getChild('2').getChildren()))
@@ -54,7 +54,7 @@ class styleNavigator(UITestCase):
# The cursor is on text with paragraph direct formatting
self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
self.assertEqual(139, len(xListBox.getChild('0').getChild('0').getChildren()))
self.assertEqual(140, len(xListBox.getChild('0').getChild('0').getChildren()))
xParDirFormatting = xListBox.getChild('1')
self.assertEqual(7, len(xParDirFormatting.getChildren()))
@@ -75,7 +75,7 @@ class styleNavigator(UITestCase):
xParStyle = xListBox.getChild('0')
self.assertEqual(3, len(xParStyle.getChildren()))
self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xParStyle.getChild('0'))['Text'])
self.assertEqual(139, len(xParStyle.getChild('0').getChildren()))
self.assertEqual(140, len(xParStyle.getChild('0').getChildren()))
self.assertEqual("Heading\t", get_state_as_dict(xParStyle.getChild('1'))['Text'])
self.assertEqual(28, len(xParStyle.getChild('1').getChildren()))
@@ -109,7 +109,7 @@ class styleNavigator(UITestCase):
xParStyle = xListBox.getChild('0')
self.assertEqual(3, len(xParStyle.getChildren()))
self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xParStyle.getChild('0'))['Text'])
self.assertEqual(139, len(xParStyle.getChild('0').getChildren()))
self.assertEqual(140, len(xParStyle.getChild('0').getChildren()))
self.assertEqual("Text Body\t", get_state_as_dict(xParStyle.getChild('1'))['Text'])
self.assertEqual(6, len(xParStyle.getChild('1').getChildren()))
@@ -144,7 +144,7 @@ class styleNavigator(UITestCase):
# The cursor is on text without metadata
self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
self.assertEqual(139, len(xListBox.getChild('0').getChild('0').getChildren()))
self.assertEqual(140, len(xListBox.getChild('0').getChild('0').getChildren()))
self.assertEqual(0, len(xListBox.getChild('1').getChildren()))
self.assertEqual(0, len(xListBox.getChild('2').getChildren()))
self.assertEqual(0, len(xListBox.getChild('3').getChildren()))
@@ -154,7 +154,7 @@ class styleNavigator(UITestCase):
# The cursor is on text with paragraph metadata showed under direct paragraph formatting
self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
self.assertEqual(139, len(xListBox.getChild('0').getChild('0').getChildren()))
self.assertEqual(140, len(xListBox.getChild('0').getChild('0').getChildren()))
xParDirFormatting = xListBox.getChild('1')
self.assertEqual(1, len(xParDirFormatting.getChildren()))
@@ -207,7 +207,7 @@ class styleNavigator(UITestCase):
# The cursor is on text without metadata
self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
self.assertEqual(139, len(xListBox.getChild('0').getChild('0').getChildren()))
self.assertEqual(140, len(xListBox.getChild('0').getChild('0').getChildren()))
self.assertEqual(0, len(xListBox.getChild('1').getChildren()))
self.assertEqual(0, len(xListBox.getChild('2').getChildren()))
self.assertEqual(0, len(xListBox.getChild('3').getChildren()))
@@ -217,7 +217,7 @@ class styleNavigator(UITestCase):
# The cursor is on text with paragraph metadata showed under direct paragraph formatting
self.assertEqual(1, len(xListBox.getChild('1').getChildren()))
self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('1').getChild('0'))['Text'])
self.assertEqual(139, len(xListBox.getChild('1').getChild('0').getChildren()))
self.assertEqual(140, len(xListBox.getChild('1').getChild('0').getChildren()))
# Outer bookmark
xBookmarkFormatting = xListBox.getChild('0')
@@ -264,7 +264,7 @@ class styleNavigator(UITestCase):
# The cursor is on text without metadata
self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
self.assertEqual(139, len(xListBox.getChild('0').getChild('0').getChildren()))
self.assertEqual(140, len(xListBox.getChild('0').getChild('0').getChildren()))
self.assertEqual(0, len(xListBox.getChild('1').getChildren()))
self.assertEqual(0, len(xListBox.getChild('2').getChildren()))
diff --git a/sw/qa/uitest/styleInspector/tdf137513.py b/sw/qa/uitest/styleInspector/tdf137513.py
index 8dfc592..a0c9dda 100644
--- a/sw/qa/uitest/styleInspector/tdf137513.py
+++ b/sw/qa/uitest/styleInspector/tdf137513.py
@@ -35,7 +35,7 @@ class tdf137513(UITestCase):
self.assertEqual(2, len(xListBox.getChild('0').getChildren()))
self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
self.assertEqual("Table Contents\t", get_state_as_dict(xListBox.getChild('0').getChild('1'))['Text'])
self.assertEqual(139, len(xListBox.getChild('0').getChild('0').getChildren()))
self.assertEqual(140, len(xListBox.getChild('0').getChild('0').getChildren()))
xTableContent = xListBox.getChild('0').getChild('1')
self.assertEqual(5, len(xTableContent.getChildren()))
diff --git a/sw/source/core/text/guess.cxx b/sw/source/core/text/guess.cxx
index d2711d4..3055c69 100644
--- a/sw/source/core/text/guess.cxx
+++ b/sw/source/core/text/guess.cxx
@@ -196,29 +196,69 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, SwTextFormatInfo &rInf,
// considering an additional "-" for hyphenation
if( bHyph )
{
// search start of the last word, if needed
sal_Int32 nLastWord = rInf.GetText().getLength() - 1;
bool bHyphenationNoLastWord = false;
// nHyphZone is the first character not fitting in the hyphenation zone,
// or 0, if the whole line in the hyphenation zone,
// or -1, if no hyphenation zone defined (i.e. it is 0)
sal_Int32 nHyphZone = -1;
const css::beans::PropertyValues & rHyphValues = rInf.GetHyphValues();
assert( rHyphValues.getLength() > 3 && rHyphValues[3].Name == UPN_HYPH_NO_LAST_WORD );
if ( rHyphValues[3].Value >>= bHyphenationNoLastWord )
{
bool bCutBlank = false;
for (; sal_Int32(rInf.GetIdx()) <= nLastWord; --nLastWord )
{
sal_Unicode cChar = rInf.GetText()[nLastWord];
if ( cChar != CH_BLANK && cChar != CH_FULL_BLANK && cChar != CH_SIX_PER_EM )
bCutBlank = true;
else if ( bCutBlank )
break;
}
}
assert( rHyphValues.getLength() > 5 && rHyphValues[5].Name == UPN_HYPH_ZONE );
// hyphenation zone (distance from the line end in twips)
sal_uInt16 nTextHyphenZone;
if ( rHyphValues[5].Value >>= nTextHyphenZone )
nHyphZone = nTextHyphenZone >= nLineWidth
? 0
: sal_Int32(rInf.GetTextBreak( nLineWidth - nTextHyphenZone,
nMaxLen, nMaxComp, rInf.GetCachedVclData().get() ));
m_nCutPos = rInf.GetTextBreak( nLineWidth, nMaxLen, nMaxComp, nHyphPos, rInf.GetCachedVclData().get() );
// don't hyphenate last word of the paragraph
if ( bHyphenationNoLastWord && sal_Int32(m_nCutPos) > nLastWord )
m_nCutPos = TextFrameIndex(nLastWord);
// don't try to hyphenate in the hyphenation zone
if ( nHyphZone != -1 && TextFrameIndex(COMPLETE_STRING) != m_nCutPos )
{
sal_Int32 nZonePos = sal_Int32(m_nCutPos);
// disable hyphenation, if there is a space within the hyphenation zone
// Note: for better interoperability, not fitting space character at
// rInf.GetIdx()[nHyphZone] always disables the hyphenation, don't need to calculate
// with its fitting part. Moreover, do not check double or more spaces there, they
// are accepted outside of the hyphenation zone, too.
for (; sal_Int32(rInf.GetIdx()) <= nZonePos && nHyphZone <= nZonePos; --nZonePos )
{
sal_Unicode cChar = rInf.GetText()[nZonePos];
if ( cChar == CH_BLANK || cChar == CH_FULL_BLANK || cChar == CH_SIX_PER_EM )
{
bHyph = false;
}
}
}
// search start of the last word, if needed
if ( bHyph )
{
// nLastWord is the space character before the last word
sal_Int32 nLastWord = rInf.GetText().getLength() - 1;
bool bHyphenationNoLastWord = false;
assert( rHyphValues.getLength() > 3 && rHyphValues[3].Name == UPN_HYPH_NO_LAST_WORD );
if ( rHyphValues[3].Value >>= bHyphenationNoLastWord )
{
// skip spaces after the last word
bool bCutBlank = false;
for (; sal_Int32(rInf.GetIdx()) <= nLastWord; --nLastWord )
{
sal_Unicode cChar = rInf.GetText()[nLastWord];
if ( cChar != CH_BLANK && cChar != CH_FULL_BLANK && cChar != CH_SIX_PER_EM )
bCutBlank = true;
else if ( bCutBlank )
break;
}
}
// don't hyphenate the last word of the paragraph
if ( bHyphenationNoLastWord && sal_Int32(m_nCutPos) > nLastWord &&
TextFrameIndex(COMPLETE_STRING) != m_nCutPos )
{
m_nCutPos = TextFrameIndex(nLastWord);
}
}
if ( !nHyphPos && rInf.GetIdx() )
nHyphPos = rInf.GetIdx() - TextFrameIndex(1);
diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx
index 5a79437..c3a5068 100644
--- a/sw/source/core/text/inftxt.cxx
+++ b/sw/source/core/text/inftxt.cxx
@@ -1361,13 +1361,14 @@ void SwTextPaintInfo::DrawViewOpt( const SwLinePortion &rPor,
static void lcl_InitHyphValues( PropertyValues &rVals,
sal_Int16 nMinLeading, sal_Int16 nMinTrailing,
bool bNoCapsHyphenation, bool bNoLastWordHyphenation, sal_Int16 nMinWordLength )
bool bNoCapsHyphenation, bool bNoLastWordHyphenation,
sal_Int16 nMinWordLength, sal_Int16 nTextHyphZone )
{
sal_Int32 nLen = rVals.getLength();
if (0 == nLen) // yet to be initialized?
{
rVals.realloc( 5 );
rVals.realloc( 6 );
PropertyValue *pVal = rVals.getArray();
pVal[0].Name = UPN_HYPH_MIN_LEADING;
@@ -1389,8 +1390,12 @@ static void lcl_InitHyphValues( PropertyValues &rVals,
pVal[4].Name = UPN_HYPH_MIN_WORD_LENGTH;
pVal[4].Handle = UPH_HYPH_MIN_WORD_LENGTH;
pVal[4].Value <<= nMinWordLength;
pVal[5].Name = UPN_HYPH_ZONE;
pVal[5].Handle = UPH_HYPH_ZONE;
pVal[5].Value <<= nTextHyphZone;
}
else if (5 == nLen) // already initialized once?
else if (6 == nLen) // already initialized once?
{
PropertyValue *pVal = rVals.getArray();
pVal[0].Value <<= nMinLeading;
@@ -1398,6 +1403,7 @@ static void lcl_InitHyphValues( PropertyValues &rVals,
pVal[2].Value <<= bNoCapsHyphenation;
pVal[3].Value <<= bNoLastWordHyphenation;
pVal[4].Value <<= nMinWordLength;
pVal[5].Value <<= nTextHyphZone;
}
else {
OSL_FAIL( "unexpected size of sequence" );
@@ -1406,7 +1412,7 @@ static void lcl_InitHyphValues( PropertyValues &rVals,
const PropertyValues & SwTextFormatInfo::GetHyphValues() const
{
OSL_ENSURE( 4 == m_aHyphVals.getLength(),
OSL_ENSURE( 6 == m_aHyphVals.getLength(),
"hyphenation values not yet initialized" );
return m_aHyphVals;
}
@@ -1427,8 +1433,10 @@ bool SwTextFormatInfo::InitHyph( const bool bAutoHyphen )
const sal_Int16 nMinimalWordLength = rAttr.GetMinWordLength();
const bool bNoCapsHyphenation = rAttr.IsNoCapsHyphenation();
const bool bNoLastWordHyphenation = rAttr.IsNoLastWordHyphenation();
const sal_Int16 nTextHyphZone = rAttr.GetTextHyphenZone();
lcl_InitHyphValues( m_aHyphVals, nMinimalLeading, nMinimalTrailing,
bNoCapsHyphenation, bNoLastWordHyphenation, nMinimalWordLength );
bNoCapsHyphenation, bNoLastWordHyphenation,
nMinimalWordLength, nTextHyphZone );
}
return bAuto;
}
diff --git a/sw/source/core/unocore/unomapproperties.hxx b/sw/source/core/unocore/unomapproperties.hxx
index 1f679b2..da2d4d9 100644
--- a/sw/source/core/unocore/unomapproperties.hxx
+++ b/sw/source/core/unocore/unomapproperties.hxx
@@ -118,6 +118,7 @@
{ u"" UNO_NAME_PARA_HYPHENATION_MAX_TRAILING_CHARS, RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_TRAIL }, \
{ u"" UNO_NAME_PARA_HYPHENATION_MAX_HYPHENS, RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MAX_HYPHENS }, \
{ u"" UNO_NAME_PARA_HYPHENATION_MIN_WORD_LENGTH, RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_WORD_LENGTH }, \
{ u"" UNO_NAME_PARA_HYPHENATION_ZONE, RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_ZONE}, \
{ u"" UNO_NAME_CHAR_AUTO_KERNING, RES_CHRATR_AUTOKERN, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
{ u"" UNO_NAME_CHAR_BACK_COLOR, RES_CHRATR_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_BACK_COLOR }, \
{ u"" UNO_NAME_CHAR_HIGHLIGHT, RES_CHRATR_HIGHLIGHT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_BACK_COLOR }, \
@@ -442,6 +443,7 @@
{ u"" UNO_NAME_PARA_HYPHENATION_MAX_TRAILING_CHARS, RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_TRAIL },\
{ u"" UNO_NAME_PARA_HYPHENATION_MAX_HYPHENS, RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MAX_HYPHENS},\
{ u"" UNO_NAME_PARA_HYPHENATION_MIN_WORD_LENGTH, RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_WORD_LENGTH},\
{ u"" UNO_NAME_PARA_HYPHENATION_ZONE, RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_ZONE},\
{ u"" UNO_NAME_NUMBERING_STYLE_NAME, RES_PARATR_NUMRULE, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},\
{ UNO_NAME_NUMBERING_LEVEL, RES_PARATR_LIST_LEVEL, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, 0},\
{ u"" UNO_NAME_PARA_USER_DEFINED_ATTRIBUTES, RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },\
diff --git a/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx b/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx
index 530f72c..9137033 100644
--- a/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx
+++ b/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx
@@ -258,6 +258,7 @@ static OUString PropertyNametoRID(const OUString& rName)
{ "ParaHyphenationNoCaps", RID_PARA_HYPHENATION_NO_CAPS },
{ "ParaHyphenationNoLastWord", RID_PARA_HYPHENATION_NO_LAST_WORD },
{ "ParaHyphenationMinWordLength", RID_PARA_HYPHENATION_MIN_WORD_LENGTH },
{ "ParaHyphenationZone", RID_PARA_HYPHENATION_ZONE },
{ "ParaInteropGrabBag", RID_PARA_INTEROP_GRAB_BAG },
{ "ParaIsAutoFirstLineIndent", RID_PARA_IS_AUTO_FIRST_LINE_INDENT },
{ "ParaIsCharacterDistance", RID_PARA_IS_CHARACTER_DISTANCE },
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index 356b980..efdd8a9 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -1066,6 +1066,7 @@ namespace xmloff::token {
TOKEN( "hyphenation-no-caps", XML_HYPHENATION_NO_CAPS ),
TOKEN( "hyphenation-no-last-word", XML_HYPHENATION_NO_LAST_WORD ),
TOKEN( "hyphenation-word-char-count", XML_HYPHENATION_WORD_CHAR_COUNT ),
TOKEN( "hyphenation-zone", XML_HYPHENATION_ZONE ),
TOKEN( "i", XML_I ),
TOKEN( "icon", XML_ICON ),
TOKEN( "icon-set", XML_ICON_SET ),
diff --git a/xmloff/source/text/txtprmap.cxx b/xmloff/source/text/txtprmap.cxx
index a2e110e..66bda55 100644
--- a/xmloff/source/text/txtprmap.cxx
+++ b/xmloff/source/text/txtprmap.cxx
@@ -345,6 +345,7 @@ XMLPropertyMapEntry const aXMLParaPropMap[] =
MAP_EXT( "ParaHyphenationNoCaps", XML_NAMESPACE_LO_EXT, XML_HYPHENATION_NO_CAPS, XML_TYPE_BOOL|XML_TYPE_PROP_TEXT, 0 ),
MAP_EXT( "ParaHyphenationNoLastWord", XML_NAMESPACE_LO_EXT, XML_HYPHENATION_NO_LAST_WORD, XML_TYPE_BOOL|XML_TYPE_PROP_TEXT, 0 ),
MAP_EXT( "ParaHyphenationMinWordLength", XML_NAMESPACE_LO_EXT, XML_HYPHENATION_WORD_CHAR_COUNT, XML_TYPE_NUMBER16_NONE|XML_TYPE_PROP_TEXT, 0 ),
MAP_EXT( "ParaHyphenationZone", XML_NAMESPACE_LO_EXT, XML_HYPHENATION_ZONE, XML_TYPE_NUMBER16_NONE|XML_TYPE_PROP_TEXT, 0 ),
// RES_PARATR_DROP
MP_E( "DropCapWholeWord", STYLE, LENGTH, MID_FLAG_SPECIAL_ITEM|XML_TYPE_BOOL, CTF_DROPCAPWHOLEWORD ),
MP_E( "DropCapCharStyleName", STYLE, STYLE_NAME, MID_FLAG_SPECIAL_ITEM|XML_TYPE_STRING, CTF_DROPCAPCHARSTYLE ),
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index ee0adc3..aaf1442 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -966,6 +966,7 @@ hyphenation-remain-char-count
hyphenation-no-caps
hyphenation-no-last-word
hyphenation-word-char-count
hyphenation-zone
i
icon
icon-set