include/oox/export/utils.hxx                                              |    
4 
 oox/source/drawingml/lineproperties.cxx                                   |   
15 +-
 oox/source/drawingml/linepropertiescontext.cxx                            |   
46 +++++++
 oox/source/export/drawingml.cxx                                           |   
49 +++++--
 sw/qa/extras/ooxmlexport/data/dashed_line_custdash_1000th_of_percent.docx 
|binary
 sw/qa/extras/ooxmlexport/data/dashed_line_custdash_percentage.docx        
|binary
 sw/qa/extras/ooxmlexport/data/dashed_line_preset.docx                     
|binary
 sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx                               |   
62 ++++++++++
 8 files changed, 156 insertions(+), 20 deletions(-)

New commits:
commit 1af3d8a211852da5a1f130aa22e00ab329301ee7
Author: Adam Co <rattles2...@gmail.com>
Date:   Sun Jun 8 16:35:32 2014 +0300

    Rewrite import and export of custom dashes in ooxml filter (fix)
    
    The import mechanism of custom-dash (a:custDash) was wrong, and imported
    wrong values, which causes that if you would import-export-import-export -
    you would get inflated values, which might cause a corruption.
    
    The attributes for custom-dash nodes (a:ds) are of type 
'PositivePercentage'.
    Office will read percentages formatted with a trailing percent sign or
    formatted as 1000th of a percent without a trailing percent sign, but only
    write percentages as 1000th's of a percent without a trailing percent sign.
    
    During import - LO did not check if it was in '%' format or in
    '1000th of a percent' format. So that was fixed. Also - when exporting -
    it always exports now in '1000th of a percent' format.
    
    Reviewed-on: https://gerrit.libreoffice.org/9681
    Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk>
    Tested-by: Miklos Vajna <vmik...@collabora.co.uk>
    (cherry picked from commit 2211a67cc5e577f8abdcc96c9c63865be5fb988d)
    
    Conflicts:
        oox/source/export/drawingml.cxx
    
    Change-Id: I6bd74df26951974f85173227c832386c70034afb

diff --git a/include/oox/export/utils.hxx b/include/oox/export/utils.hxx
index 588d231..2c4fcec 100644
--- a/include/oox/export/utils.hxx
+++ b/include/oox/export/utils.hxx
@@ -50,9 +50,9 @@ static inline sal_Int64 TwipsToEMU( sal_Int32 nTwips )
 }
 
 template <typename T>
-OString writePercentage(T number)
+OString write1000thOfAPercent(T number)
 {
-    return OString::number(number) + "%";
+    return OString::number( number * 1000 );
 }
 
 #endif
diff --git a/oox/source/drawingml/lineproperties.cxx 
b/oox/source/drawingml/lineproperties.cxx
index 2044095..372740b 100644
--- a/oox/source/drawingml/lineproperties.cxx
+++ b/oox/source/drawingml/lineproperties.cxx
@@ -107,19 +107,26 @@ void lclConvertCustomDash( LineDash& orLineDash, const 
LineProperties::DashStopV
     sal_Int16 nDashes = 0;
     sal_Int32 nDashLen = 0;
     sal_Int32 nDistance = 0;
+    sal_Int32 nConvertedLen = 0;
+    sal_Int32 nConvertedDistance = 0;
     for( LineProperties::DashStopVector::const_iterator aIt = 
rCustomDash.begin(), aEnd = rCustomDash.end(); aIt != aEnd; ++aIt )
     {
-        if( aIt->first <= 2 )
+        // Get from "1000th of percent" ==> percent ==> multiplier
+        nConvertedLen      = aIt->first  / 1000 / 100;
+        nConvertedDistance = aIt->second / 1000 / 100;
+
+        // Check if it is a dot (100% = dot)
+        if( nConvertedLen == 1 )
         {
             ++nDots;
-            nDotLen += aIt->first;
+            nDotLen += nConvertedLen;
         }
         else
         {
             ++nDashes;
-            nDashLen += aIt->first;
+            nDashLen += nConvertedLen;
         }
-        nDistance += aIt->second;
+        nDistance += nConvertedDistance;
     }
     orLineDash.DotLen = (nDots > 0) ? ::std::max< sal_Int32 >( nDotLen / 
nDots, 1 ) : 0;
     orLineDash.Dots = nDots;
diff --git a/oox/source/drawingml/linepropertiescontext.cxx 
b/oox/source/drawingml/linepropertiescontext.cxx
index 3195e56..ee49fba 100644
--- a/oox/source/drawingml/linepropertiescontext.cxx
+++ b/oox/source/drawingml/linepropertiescontext.cxx
@@ -66,8 +66,50 @@ ContextHandlerRef LinePropertiesContext::onCreateContext( 
sal_Int32 nElement, co
             return this;
         break;
         case A_TOKEN( ds ):
-            mrLineProperties.maCustomDash.push_back( LineProperties::DashStop(
-                rAttribs.getInteger( XML_d, 0 ), rAttribs.getInteger( XML_sp, 
0 ) ) );
+        {
+            // 'a:ds' has 2 attributes : 'd' and 'sp'
+            // both are of type 'a:ST_PositivePercentage'
+            // according to the specs Office will read percentages formatted 
with a trailing percent sign
+            // or formatted as 1000th of a percent without a trailing percent 
sign, but only write percentages
+            // as 1000th's of a percent without a trailing percent sign.
+            // The code below takes care of both scenarios by converting to 
'1000th of a percent' always
+            OUString aStr;
+            sal_Int32 nDash = 0;
+            aStr = rAttribs.getString( XML_d, "" );
+            if ( aStr.endsWith("%") )
+            {
+                // Ends with a '%'
+                aStr = aStr.copy(0, aStr.getLength() - 1);
+                aStr = aStr.trim();
+                nDash = aStr.toInt32();
+
+                // Convert to 1000th of a percent
+                nDash *= 1000;
+            }
+            else
+            {
+                nDash = rAttribs.getInteger( XML_d, 0 );
+            }
+
+            sal_Int32 nSp = 0;
+            aStr = rAttribs.getString( XML_sp, "" );
+            if ( aStr.endsWith("%") )
+            {
+                // Ends with a '%'
+                aStr = aStr.copy(0, aStr.getLength() - 1);
+                aStr = aStr.trim();
+                nSp = aStr.toInt32();
+
+                // Convert to 1000th of a percent
+                nSp *= 1000;
+            }
+            else
+            {
+                nSp = rAttribs.getInteger( XML_sp, 0 );
+            }
+
+            mrLineProperties.maCustomDash.push_back( LineProperties::DashStop( 
nDash, nSp ) );
+        }
         break;
 
         // LineJoinPropertiesGroup
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 2ef0d1f..641cb4d 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -626,19 +626,44 @@ void DrawingML::WriteOutline( Reference< XPropertySet > 
rXPropSet )
 
     if( bDashSet && aStyleLineStyle != drawing::LineStyle_DASH ) {
         // line style is a dash and it was not set by the shape style
-        // TODO: the XML_d and XML_sp values seem insane
+
         mpFS->startElementNS( XML_a, XML_custDash, FSEND );
-        int i;
-        for( i = 0; i < aLineDash.Dots; i ++ )
-            mpFS->singleElementNS( XML_a, XML_ds,
-                                   XML_d, aLineDash.DotLen ? writePercentage( 
aLineDash.DotLen*1000 ) : "100000%",
-                                   XML_sp, writePercentage( 
aLineDash.Distance*1000 ),
-                                   FSEND );
-        for( i = 0; i < aLineDash.Dashes; i ++ )
-            mpFS->singleElementNS( XML_a, XML_ds,
-                                   XML_d, aLineDash.DashLen ? writePercentage( 
aLineDash.DashLen*1000 ) : "100000%",
-                                   XML_sp, writePercentage( 
aLineDash.Distance*1000 ),
-                                   FSEND );
+
+        // Check that line-width is positive and distance between dashes\dots 
is positive
+        if ( nLineWidth > 0 && aLineDash.Distance > 0 )
+        {
+            // Write 'dashes' first, and then 'dots'
+            int i;
+            if ( aLineDash.Dashes > 0 )
+            {
+                for( i = 0; i < aLineDash.Dashes; i ++ )
+                    mpFS->singleElementNS( XML_a , XML_ds,
+                                           XML_d , write1000thOfAPercent( 
aLineDash.DashLen  > 0 ? aLineDash.DashLen  / nLineWidth * 100 : 100 ),
+                                           XML_sp, write1000thOfAPercent( 
aLineDash.Distance > 0 ? aLineDash.Distance / nLineWidth * 100 : 100 ),
+                                           FSEND );
+            }
+            if ( aLineDash.Dots > 0 )
+            {
+                for( i = 0; i < aLineDash.Dots; i ++ )
+                    mpFS->singleElementNS( XML_a, XML_ds,
+                                           XML_d , write1000thOfAPercent( 
aLineDash.DotLen   > 0 ? aLineDash.DotLen   / nLineWidth * 100 : 100 ),
+                                           XML_sp, write1000thOfAPercent( 
aLineDash.Distance > 0 ? aLineDash.Distance / nLineWidth * 100 : 100 ),
+                                           FSEND );
+            }
+        }
+
+        if ( nLineWidth <= 0 )
+            SAL_WARN("oox", "while writing outline - custom dash - line width 
was < 0  : " << nLineWidth);
+        if ( aLineDash.Dashes < 0 )
+            SAL_WARN("oox", "while writing outline - custom dash - number of 
dashes was < 0  : " << aLineDash.Dashes);
+        if ( aLineDash.Dashes > 0 && aLineDash.DashLen <= 0 )
+            SAL_WARN("oox", "while writing outline - custom dash - dash length 
was < 0  : " << aLineDash.DashLen);
+        if ( aLineDash.Dots < 0 )
+            SAL_WARN("oox", "while writing outline - custom dash - number of 
dots was < 0  : " << aLineDash.Dots);
+        if ( aLineDash.Dots > 0 && aLineDash.DotLen <= 0 )
+            SAL_WARN("oox", "while writing outline - custom dash - dot length 
was < 0  : " << aLineDash.DotLen);
+        if ( aLineDash.Distance <= 0 )
+            SAL_WARN("oox", "while writing outline - custom dash - distance 
was < 0  : " << aLineDash.Distance);
         mpFS->endElementNS( XML_a, XML_custDash );
     }
 
diff --git 
a/sw/qa/extras/ooxmlexport/data/dashed_line_custdash_1000th_of_percent.docx 
b/sw/qa/extras/ooxmlexport/data/dashed_line_custdash_1000th_of_percent.docx
new file mode 100755
index 0000000..d9a9228
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/dashed_line_custdash_1000th_of_percent.docx 
differ
diff --git a/sw/qa/extras/ooxmlexport/data/dashed_line_custdash_percentage.docx 
b/sw/qa/extras/ooxmlexport/data/dashed_line_custdash_percentage.docx
new file mode 100755
index 0000000..a1d0e7d
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/dashed_line_custdash_percentage.docx differ
diff --git a/sw/qa/extras/ooxmlexport/data/dashed_line_preset.docx 
b/sw/qa/extras/ooxmlexport/data/dashed_line_preset.docx
new file mode 100755
index 0000000..923360b
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/dashed_line_preset.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx
index 142d087..700506d 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx
@@ -1519,6 +1519,68 @@ DECLARE_OOXMLEXPORT_TEST(testBnc884615, "bnc884615.docx")
     CPPUNIT_ASSERT_EQUAL(false, bool(getProperty<sal_Bool>(getShape(1), 
"Opaque")));
 }
 
+DECLARE_OOXMLEXPORT_TEST(testDashedLinePreset, "dashed_line_preset.docx")
+{
+    /* Make sure that preset line is exported correctly as "1000th of a 
percent".
+     * This test-file has a PRESET dash-line which will be converted by LO 
import
+     * to a custom-dash (dash-dot-dot). This test-case makes sure that the 
exporter
+     * outputs the correct values.
+     */
+    xmlDocPtr pXmlDoc = parseExport("word/document.xml");
+    if (!pXmlDoc)
+        return;
+
+    
assertXPath(pXmlDoc,"/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:ln[1]/a:custDash[1]/a:ds[1]",
 "d" , "800000");
+    
assertXPath(pXmlDoc,"/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:ln[1]/a:custDash[1]/a:ds[1]",
 "sp", "300000");
+
+    
assertXPath(pXmlDoc,"/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:ln[1]/a:custDash[1]/a:ds[2]",
 "d" , "100000");
+    
assertXPath(pXmlDoc,"/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:ln[1]/a:custDash[1]/a:ds[2]",
 "sp", "300000");
+
+    
assertXPath(pXmlDoc,"/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:ln[1]/a:custDash[1]/a:ds[3]",
 "d" , "100000");
+    
assertXPath(pXmlDoc,"/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:ln[1]/a:custDash[1]/a:ds[3]",
 "sp", "300000");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testDashedLine_CustDash1000thOfPercent, 
"dashed_line_custdash_1000th_of_percent.docx")
+{
+    /* Make sure that preset line is exported correctly as "1000th of a 
percent".
+     * This test-file has a CUSTOM dash-line that is defined as '1000th of a 
percent'.
+     * This should be imported by LO as-is, and exported back with the same 
values.
+     */
+    xmlDocPtr pXmlDoc = parseExport("word/document.xml");
+    if (!pXmlDoc)
+        return;
+
+    
assertXPath(pXmlDoc,"/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:ln[1]/a:custDash[1]/a:ds[1]",
 "d" , "800000");
+    
assertXPath(pXmlDoc,"/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:ln[1]/a:custDash[1]/a:ds[1]",
 "sp", "300000");
+
+    
assertXPath(pXmlDoc,"/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:ln[1]/a:custDash[1]/a:ds[2]",
 "d" , "100000");
+    
assertXPath(pXmlDoc,"/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:ln[1]/a:custDash[1]/a:ds[2]",
 "sp", "300000");
+
+    
assertXPath(pXmlDoc,"/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:ln[1]/a:custDash[1]/a:ds[3]",
 "d" , "100000");
+    
assertXPath(pXmlDoc,"/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:ln[1]/a:custDash[1]/a:ds[3]",
 "sp", "300000");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testDashedLine_CustDashPercentage, 
"dashed_line_custdash_percentage.docx")
+{
+    /* Make sure that preset line is exported correctly as "1000th of a 
percent".
+     * This test-file has a CUSTOM dash-line that is defined as percentages.
+     * This should be imported by LO as '1000th of a percent', and exported 
back
+     * as '1000th of a percent'.
+     */
+    xmlDocPtr pXmlDoc = parseExport("word/document.xml");
+    if (!pXmlDoc)
+        return;
+
+    
assertXPath(pXmlDoc,"/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:ln[1]/a:custDash[1]/a:ds[1]",
 "d" , "800000");
+    
assertXPath(pXmlDoc,"/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:ln[1]/a:custDash[1]/a:ds[1]",
 "sp", "300000");
+
+    
assertXPath(pXmlDoc,"/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:ln[1]/a:custDash[1]/a:ds[2]",
 "d" , "100000");
+    
assertXPath(pXmlDoc,"/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:ln[1]/a:custDash[1]/a:ds[2]",
 "sp", "300000");
+
+    
assertXPath(pXmlDoc,"/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:ln[1]/a:custDash[1]/a:ds[3]",
 "d" , "100000");
+    
assertXPath(pXmlDoc,"/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:ln[1]/a:custDash[1]/a:ds[3]",
 "sp", "300000");
+}
+
 #endif
 
 CPPUNIT_PLUGIN_IMPLEMENT();
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to