sw/qa/extras/ooxmlexport/ooxmlexport13.cxx                |   13 +++---
 sw/qa/extras/ww8export/data/tdf127316_autoEscapement2.odt |binary
 sw/qa/extras/ww8export/ww8export3.cxx                     |   21 +++++++--
 sw/source/filter/ww8/docxattributeoutput.cxx              |   18 ++++++--
 sw/source/filter/ww8/rtfattributeoutput.cxx               |   30 ++++++--------
 sw/source/filter/ww8/ww8atr.cxx                           |   17 ++++++-
 6 files changed, 64 insertions(+), 35 deletions(-)

New commits:
commit d6e2d624a124454fa4ac80cb30a924571a609101
Author:     Justin Luth <justin_l...@sil.org>
AuthorDate: Sat Oct 5 21:23:04 2019 +0300
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon Nov 25 09:08:35 2019 +0100

    tdf#127316 ooxml/ww8export: DFLT_ESC_*_AUTO - use better formulas
    
    See tdf#99602 and tdf#120412 for many fixes related to escapement.
    The poor formulas for AUTO style came to light in 6.3.0.1
    with 6.4 commit 32262b0a537207832d7d126d8427d8949b9e821d
    
    Looking at sw/source/core/txtnode/swfont.cxx, we can see in
    CalcEsc() that for superscript the DFLT_ESC_SUPER_AUTO
    is calculated as the difference between the two ascents.
    Because the superscript is smaller, it has a smaller ascent,
    so to reach the same ascent line as the original, we can
    raise its baseline by fontAscent(fA) - superscriptAscent(ssA).
    Since the ascent is approximately 80% of the total fontheight(fH),
    we can calculate the Esc number (percentage * 100) as:
    EscHeight = fA - ssA  (formula in CalcEsc)
    ssA = nProp/100 * fA  (superscript ascent/height reduced by nProp)
    .8 = fA/fHeight       (improvement would be to query font.GetAscent)
    Esc% = EscHeight / fHeight
    
    Esc% = (fA - nProp/100*fA) / fHeight
    Esc% = (1 - nProp/100)*fA/fHeight
    Esc = (100 - nProp) * 0.8
    
    DFLT_ESC_SUB_AUTO subscript is similar with the descent(fD)
    being the remainding 20% of the fontHeight.
    EscHeight = fD - ssD (formula in CalcEsc)
    ssD = nProp/100 * fD (by definition of the function of nProp)
    .2 = fD/fHeight      (an approximation - each font will be different)
    
    Esc% = (fD - nProp/100*fD) / fHeight
    Esc% = (1 - nProp/100)*fD/fHeight
    Esc = (100 - nProp) * 0.2 (in the negative direction)
    
    For RTF, I can see no reason for the ++nProp except
    to try and avoid nProp == 0. It is only .01% after all...
    
    Change-Id: Ia7b9f8784572193dd05cb80afa56c90540c3e676
    Reviewed-on: https://gerrit.libreoffice.org/80306
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <justin_l...@sil.org>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
index 7294824b62ff..64c1fc6cc10a 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
@@ -224,21 +224,24 @@ 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
+    // This should be roughly .8*35% of the ORIGINAL(non-reduced) size. 
However, during export the
     // proportional height has to be changed into direct formatting, which 
then changes the relative percent.
     // In this case, a 24pt font, proportional at 65% becomes roughly a 16pt 
font.
-    // Thus an escapement of 33% (8pt) becomes roughly 50% for the 16pt font.
+    // Thus an escapement of 28% (6.72pt) becomes roughly 42% 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);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(42.f, getProperty<float>(getRun(xPara, 2), 
"CharEscapement"), 1);
 
     // 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);
+    // This should be roughly .2*35% of the ORIGINAL (non-reduced) size. 
However, during export the
+    // proportional height has to be changed into direct formatting, which 
then changes the relative percent.
+    // In this case, a 24pt font, proportional at 65% becomes roughly a 16pt 
font.
+    // Thus an escapement of 7% (1.68pt) becomes roughly 10.5% for the 16pt 
font.
+    CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Subscript", -10.f, 
getProperty<float>(getRun(xPara, 2), "CharEscapement"), 1);
 }
 
 DECLARE_OOXMLEXPORT_TEST(testTdf99602_subscript_charStyleSize, 
"tdf99602_subscript_charStyleSize.docx")
diff --git a/sw/qa/extras/ww8export/data/tdf127316_autoEscapement2.odt 
b/sw/qa/extras/ww8export/data/tdf127316_autoEscapement2.odt
new file mode 100644
index 000000000000..d98fae0ad4d6
Binary files /dev/null and 
b/sw/qa/extras/ww8export/data/tdf127316_autoEscapement2.odt differ
diff --git a/sw/qa/extras/ww8export/ww8export3.cxx 
b/sw/qa/extras/ww8export/ww8export3.cxx
index 014274e98bbf..d4a65e685f4a 100644
--- a/sw/qa/extras/ww8export/ww8export3.cxx
+++ b/sw/qa/extras/ww8export/ww8export3.cxx
@@ -177,11 +177,24 @@ DECLARE_WW8EXPORT_TEST(testTdf127316_autoEscapement, 
"tdf127316_autoEscapement.o
 {
     uno::Reference<text::XTextRange> xPara = getParagraph(2);
     CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f, getProperty<float>(getRun(xPara, 1, 
"Normal text "), "CharEscapement"), 0);
-    // 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.
     // Negative escapements (subscripts) were decreasing by 1% every 
round-trip due to bad manual rounding.
-    // The actual number of 50% 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?", -50.f, 
getProperty<float>(getRun(xPara, 2), "CharEscapement"), 1);
+    // This should be roughly .2*35% of the ORIGINAL (non-reduced) size. 
However, during export the
+    // proportional height has to be changed into direct formatting, which 
then changes the relative percent.
+    // In this case, a 24pt font, proportional at 65% becomes roughly a 16pt 
font.
+    // Thus an escapement of 7% (1.68pt) becomes roughly 10.5% for the 16pt 
font.
+    CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Subscript", -10.f, 
getProperty<float>(getRun(xPara, 2), "CharEscapement"), 1);
+}
+
+DECLARE_WW8EXPORT_TEST(testTdf127316_autoEscapement2, 
"tdf127316_autoEscapement2.odt")
+{
+    uno::Reference<text::XTextRange> xPara = getParagraph(1);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f, getProperty<float>(getRun(xPara, 1, 
"Base1"), "CharEscapement"), 0);
+    // Font is 80% of 40pt or 32pt, original escapement is 6.4pt, so 
round-trip escapement is 20%.
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(20.f, getProperty<float>(getRun(xPara, 
2,"AutoSuperscript"), "CharEscapement"), 1);
+    xPara.set( getParagraph(3) );
+    CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f, getProperty<float>(getRun(xPara, 1, 
"Base3"), "CharEscapement"), 0);
+    // font is 20% of 40pt or 8pt, original escapement is 25.6pt, so 
round-trip escapement is 320%.
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(320.f, getProperty<float>(getRun(xPara, 
2,"AutoSuperscript"), "CharEscapement"), 3);
 }
 
 DECLARE_WW8EXPORT_TEST(testTdf120412_proportionalEscapement, 
"tdf120412_proportionalEscapement.odt")
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 152a947c3afb..9e4f6769a6d4 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -6842,19 +6842,27 @@ void DocxAttributeOutput::CharEscapement( const 
SvxEscapementItem& rEscapement )
         nEsc = 0;
         nProp = 100;
     }
-    else if ( DFLT_ESC_PROP == nProp )
+    else if ( DFLT_ESC_PROP == nProp || nProp < 1 || nProp > 100 )
     {
         if ( DFLT_ESC_SUB == nEsc || DFLT_ESC_AUTO_SUB == nEsc )
             sIss = OString( "subscript" );
         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
+    {
+        // Raised by the differences between the ascenders (ascent = baseline 
to top of highest letter).
+        // The ascent is generally about 80% of the total font height.
+        // That is why DFLT_ESC_PROP (58) leads to 33% (DFLT_ESC_SUPER)
+        nEsc = .8 * (100 - nProp);
+    }
     else if ( DFLT_ESC_AUTO_SUB == nEsc )
-        nEsc = DFLT_ESC_SUB;
+    {
+        // Lowered by the differences between the descenders (descent = 
baseline to bottom of lowest letter).
+        // The descent is generally about 20% of the total font height.
+        // That is why DFLT_ESC_PROP (58) _originally_ lead to 8% 
(DFLT_ESC_SUB)
+        nEsc = .2 * -(100 - nProp);
+    }
 
     if ( !sIss.isEmpty() )
         m_pSerializer->singleElementNS(XML_w, XML_vertAlign, FSNS(XML_w, 
XML_val), sIss);
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx 
b/sw/source/filter/ww8/rtfattributeoutput.cxx
index 0f3fbb7c91cc..32fa51aeb74c 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -2324,8 +2324,8 @@ void RtfAttributeOutput::CharCrossedOut(const 
SvxCrossedOutItem& rCrossedOut)
 
 void RtfAttributeOutput::CharEscapement(const SvxEscapementItem& rEscapement)
 {
-    short nEsc = rEscapement.GetEsc();
-    if (rEscapement.GetProportionalHeight() == DFLT_ESC_PROP)
+    short nEsc = rEscapement.GetEsc(), nProp = 
rEscapement.GetProportionalHeight();
+    if (DFLT_ESC_PROP == nProp || nProp < 1 || nProp > 100)
     {
         if (DFLT_ESC_SUB == nEsc || DFLT_ESC_AUTO_SUB == nEsc)
             m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SUB);
@@ -2333,14 +2333,22 @@ void RtfAttributeOutput::CharEscapement(const 
SvxEscapementItem& rEscapement)
             m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SUPER);
         return;
     }
+    else if (DFLT_ESC_AUTO_SUPER == nEsc)
+    {
+        nEsc = .8 * (100 - nProp);
+    }
+    else if (DFLT_ESC_AUTO_SUB == nEsc)
+    {
+        nEsc = .2 * -(100 - nProp);
+    }
 
     const char* pUpDn;
 
     double fHeight = m_rExport.GetItem(RES_CHRATR_FONTSIZE).GetHeight();
 
-    if (0 < rEscapement.GetEsc())
+    if (0 < nEsc)
         pUpDn = OOO_STRING_SVTOOLS_RTF_UP;
-    else if (0 > rEscapement.GetEsc())
+    else if (0 > nEsc)
     {
         pUpDn = OOO_STRING_SVTOOLS_RTF_DN;
         fHeight = -fHeight;
@@ -2348,22 +2356,10 @@ void RtfAttributeOutput::CharEscapement(const 
SvxEscapementItem& rEscapement)
     else
         return;
 
-    short nProp = rEscapement.GetProportionalHeight() * 100;
-    if (DFLT_ESC_AUTO_SUPER == nEsc)
-    {
-        nEsc = 100 - rEscapement.GetProportionalHeight();
-        ++nProp;
-    }
-    else if (DFLT_ESC_AUTO_SUB == nEsc)
-    {
-        nEsc = -100 + rEscapement.GetProportionalHeight();
-        ++nProp;
-    }
-
     m_aStyles.append('{');
     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_IGNORE);
     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_UPDNPROP);
-    m_aStyles.append(static_cast<sal_Int32>(nProp));
+    m_aStyles.append(static_cast<sal_Int32>(nProp * 100));
     m_aStyles.append('}');
     m_aStyles.append(pUpDn);
 
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index b5cfddc8fde2..bb90acc939f8 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -1389,18 +1389,27 @@ void WW8AttributeOutput::CharEscapement( const 
SvxEscapementItem& rEscapement )
         nEsc = 0;
         nProp = 100;
     }
-    else if ( DFLT_ESC_PROP == nProp )
+    else if ( DFLT_ESC_PROP == nProp || nProp < 1 || nProp > 100 )
     {
         if ( DFLT_ESC_SUB == nEsc || DFLT_ESC_AUTO_SUB == nEsc )
             b = 2;
         else if ( DFLT_ESC_SUPER == nEsc || DFLT_ESC_AUTO_SUPER == nEsc )
             b = 1;
     }
-    // FIXME: these need a better formula. See rtfAttributeOutput
     else if ( DFLT_ESC_AUTO_SUPER == nEsc )
-        nEsc = DFLT_ESC_SUPER;
+    {
+        // Raised by the differences between the ascenders (ascent = baseline 
to top of highest letter).
+        // The ascent is generally about 80% of the total font height.
+        // That is why DFLT_ESC_PROP (58) leads to 33% (DFLT_ESC_SUPER)
+        nEsc = .8 * (100 - nProp);
+    }
     else if ( DFLT_ESC_AUTO_SUB == nEsc )
-        nEsc = DFLT_ESC_SUB;
+    {
+        // Lowered by the differences between the descenders (descent = 
baseline to bottom of lowest letter).
+        // The descent is generally about 20% of the total font height.
+        // That is why DFLT_ESC_PROP (58) _originally_ lead to 8% 
(DFLT_ESC_SUB)
+        nEsc = .2 * -(100 - nProp);
+    }
 
     if ( 0xFF != b )
     {
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to