related tdf#99602 docxoutput: fix incorrect rounding on subscripts
Adding .5 is a poor mans version of rounding which works fine with
unsigned numbers, but not with negative numbers. Perhaps use the
exotic round() function instead?
In addition, the font size isn't necessarily an integer,
so that should have been a float.
The result of bad rounding was losing a percentage of the subscript
every round-trip.
Change-Id: I83e05d8367f059f3266d12a7e134e268fef758bb
Reviewed-on: https://gerrit.libreoffice.org/80217
Tested-by: Jenkins
Reviewed-by: Justin Luth <justin_luth@sil.org>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
index 8122487..5f4800f 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
@@ -218,18 +218,30 @@ DECLARE_OOXMLEXPORT_TEST(testBtlrShape, "btlr-textbox.docx")
DECLARE_OOXMLEXPORT_TEST(testTdf127316_autoEscapement, "tdf127316_autoEscapement.odt")
{
// This should be roughly 33% of the ORIGINAL(non-reduced) size. However, during export the
// propertional height has to be changed into direct formating, which then changes the relative percent.
// In this case, a 24pt font, proportional at 65% becomes roughtly a 16pt font.
// Thus an escapement of 33% (8pt) becomes roughly 50% for the 16pt font.
uno::Reference<text::XTextRange> xPara = getParagraph(1);
CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f, getProperty<float>(getRun(xPara, 1), "CharEscapement"), 0);
CPPUNIT_ASSERT_DOUBLES_EQUAL(33.f, getProperty<float>(getRun(xPara, 2), "CharEscapement"), 20);
// Subscripts are different. Automatic escapement SHOULD BE limited by the font bottom line(?)
// and so the calculations ought to be different. There is room for a lot of export improvement here.
xPara.set(getParagraph(2));
CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f, getProperty<float>(getRun(xPara, 1, "Normal text "), "CharEscapement"), 0);
// Negative escapements (subscripts) were decreasing by 1% every round-trip due to bad manual rounding.
// The actual number of 52% isn't so important here, but test that it is stable across multiple round-trips.
CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Did you fix or break me?", -52.f, getProperty<float>(getRun(xPara, 2), "CharEscapement"), 2);
}
DECLARE_OOXMLEXPORT_TEST(testTdf99602_subscript_charStyleSize, "tdf99602_subscript_charStyleSize.docx")
{
uno::Reference<text::XTextRange> xPara = getParagraph(1);
// The word "Base" should not be subscripted.
CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f, getProperty<float>(getRun(xPara, 1), "CharEscapement"), 0);
CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f, getProperty<float>(getRun(xPara, 1, "Base"), "CharEscapement"), 0);
// The word "Subscript" should be 48pt, subscripted by 25% (12pt).
CPPUNIT_ASSERT_DOUBLES_EQUAL( -25.f, getProperty<float>(getRun(xPara, 2), "CharEscapement"), 1);
CPPUNIT_ASSERT_DOUBLES_EQUAL( -25.f, getProperty<float>(getRun(xPara, 2, "Subscript"), "CharEscapement"), 0);
}
DECLARE_OOXMLEXPORT_TEST(testTdf124637_sectionMargin, "tdf124637_sectionMargin.docx")
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 1d01e79..872b693 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -6847,8 +6847,10 @@ void DocxAttributeOutput::CharEscapement( const SvxEscapementItem& rEscapement )
else if ( DFLT_ESC_SUPER == nEsc || DFLT_ESC_AUTO_SUPER == nEsc )
sIss = OString( "superscript" );
}
// FIXME: these need a better formula. See rtfAttributeOutput
else if ( DFLT_ESC_AUTO_SUPER == nEsc )
nEsc = DFLT_ESC_SUPER;
// FIXME: this actually needs to know font information (descending, bottom line) for a proper formula
else if ( DFLT_ESC_AUTO_SUB == nEsc )
nEsc = DFLT_ESC_SUB;
@@ -6858,13 +6860,13 @@ void DocxAttributeOutput::CharEscapement( const SvxEscapementItem& rEscapement )
const SvxFontHeightItem& rItem = m_rExport.GetItem(RES_CHRATR_FONTSIZE);
if (sIss.isEmpty() || sIss.match("baseline"))
{
long nHeight = rItem.GetHeight();
OString sPos = OString::number( ( nHeight * nEsc + 500 ) / 1000 );
float fHeight = rItem.GetHeight();
OString sPos = OString::number( round(( fHeight * nEsc ) / 1000) );
m_pSerializer->singleElementNS(XML_w, XML_position, FSNS(XML_w, XML_val), sPos);
if( ( 100 != nProp || sIss.match( "baseline" ) ) && !m_rExport.m_bFontSizeWritten )
{
OString sSize = OString::number( ( nHeight * nProp + 500 ) / 1000 );
OString sSize = OString::number( round(( fHeight * nProp ) / 1000) );
m_pSerializer->singleElementNS(XML_w, XML_sz, FSNS(XML_w, XML_val), sSize);
}
}