sdext/source/pdfimport/inc/pdfihelper.hxx          |   33 ++++++++++
 sdext/source/pdfimport/misc/pdfihelper.cxx         |   53 +++++++++++++++++
 sdext/source/pdfimport/tree/drawtreevisiting.cxx   |   64 ++++++---------------
 sdext/source/pdfimport/tree/style.cxx              |    2 
 sdext/source/pdfimport/tree/writertreevisiting.cxx |   61 +++++---------------
 5 files changed, 125 insertions(+), 88 deletions(-)

New commits:
commit b27fca822cd6f40c8a7e56fe56fdf76bdc0dd159
Author: Vort <vv...@yandex.ru>
Date:   Sun May 4 08:49:18 2014 +0300

    fdo#78241 PDF Import: add dashes support
    
    Change-Id: Ifd9fbce44c7d18114d5be466bfb9d92192573205
    Reviewed-on: https://gerrit.libreoffice.org/9246
    Reviewed-by: Caolán McNamara <caol...@redhat.com>
    Tested-by: Caolán McNamara <caol...@redhat.com>

diff --git a/sdext/source/pdfimport/inc/pdfihelper.hxx 
b/sdext/source/pdfimport/inc/pdfihelper.hxx
index 2478a96..de589a6 100644
--- a/sdext/source/pdfimport/inc/pdfihelper.hxx
+++ b/sdext/source/pdfimport/inc/pdfihelper.hxx
@@ -28,6 +28,8 @@
 #include <basegfx/polygon/b2dpolypolygon.hxx>
 #include <basegfx/polygon/b2dpolygon.hxx>
 #include <com/sun/star/rendering/XColorSpace.hpp>
+#include "com/sun/star/rendering/PathCapType.hpp"
+#include "com/sun/star/rendering/PathJoinType.hpp"
 
 #include <vector>
 #include <boost/unordered_map.hpp>
@@ -71,6 +73,9 @@ namespace pdfi
     /// Convert color to "#FEFEFE" color notation
     OUString getColorString( const ::com::sun::star::rendering::ARGBColor& );
 
+    double GetAverageTransformationScale(const basegfx::B2DHomMatrix& matrix);
+    void FillDashStyleProps(PropertyMap& props, const std::vector<double>& 
dashArray, double scale);
+
     struct FontAttrHash
     {
         size_t operator()(const FontAttributes& rFont ) const
@@ -140,6 +145,34 @@ namespace pdfi
                 Clip == rRight.Clip;
         }
 
+        OUString GetLineJoinString() const
+        {
+            switch (LineJoin)
+            {
+            default:
+            case ::com::sun::star::rendering::PathJoinType::MITER:
+                return "miter";
+            case ::com::sun::star::rendering::PathJoinType::ROUND:
+                return "round";
+            case ::com::sun::star::rendering::PathJoinType::BEVEL:
+                return "bevel";
+            }
+        }
+
+        OUString GetLineCapString() const
+        {
+            switch (LineCap)
+            {
+            default:
+            case ::com::sun::star::rendering::PathCapType::BUTT:
+                return "butt";
+            case ::com::sun::star::rendering::PathCapType::ROUND:
+                return "round";
+            case ::com::sun::star::rendering::PathCapType::SQUARE:
+                return "square";
+            }
+        }
+
         bool isRotatedOrSkewed() const
         { return Transformation.get( 0, 1 ) != 0.0 ||
                 Transformation.get( 1, 0 ) != 0.0; }
diff --git a/sdext/source/pdfimport/misc/pdfihelper.cxx 
b/sdext/source/pdfimport/misc/pdfihelper.cxx
index 8204ad3..862f11b 100644
--- a/sdext/source/pdfimport/misc/pdfihelper.cxx
+++ b/sdext/source/pdfimport/misc/pdfihelper.cxx
@@ -23,9 +23,62 @@
 #include <rtl/ustrbuf.hxx>
 #include <basegfx/numeric/ftools.hxx>
 
+#include <math.h>
+
 using namespace pdfi;
 using namespace com::sun::star;
 
+double pdfi::GetAverageTransformationScale(const basegfx::B2DHomMatrix& matrix)
+{
+    double rotate, shearX;
+    basegfx::B2DTuple scale, translation;
+    matrix.decompose(scale, translation, rotate, shearX);
+    return (fabs(scale.getX()) + fabs(scale.getY())) / 2.0;
+}
+
+void pdfi::FillDashStyleProps(PropertyMap& props, const std::vector<double>& 
dashArray, double scale)
+{
+    size_t pairCount = dashArray.size() / 2;
+
+    double distance = 0.0;
+    for (size_t i = 0; i < pairCount; i++)
+        distance += dashArray[i * 2 + 1];
+    distance /= pairCount;
+
+    props["draw:style"] = "rect";
+    props["draw:distance"] = convertPixelToUnitString(distance * scale);
+
+    int dotStage = 0;
+    int dotCounts[3] = {0, 0, 0};
+    double dotLengths[3] = {0.0, 0.0, 0.0};
+
+    for (size_t i = 0; i < pairCount; i++)
+    {
+        if (dotLengths[dotStage] != dashArray[i * 2])
+        {
+            dotStage++;
+            if (dotStage == 3)
+                break;
+
+            dotCounts[dotStage] = 1;
+            dotLengths[dotStage] = dashArray[i * 2];
+        }
+        else
+        {
+            dotCounts[dotStage]++;
+        }
+    }
+
+    for (int i = 1; i < 3; i++)
+    {
+        if (dotCounts[i] == 0)
+            continue;
+        props["draw:dots" + OUString::number(i)] = 
OUString::number(dotCounts[i]);
+        props["draw:dots" + OUString::number(i) + "-length"] =
+            convertPixelToUnitString(dotLengths[i] * scale);
+    }
+}
+
 OUString pdfi::getColorString( const rendering::ARGBColor& rCol )
 {
     OUStringBuffer aBuf( 7 );
diff --git a/sdext/source/pdfimport/tree/drawtreevisiting.cxx 
b/sdext/source/pdfimport/tree/drawtreevisiting.cxx
index acf9ff7..49c1959 100644
--- a/sdext/source/pdfimport/tree/drawtreevisiting.cxx
+++ b/sdext/source/pdfimport/tree/drawtreevisiting.cxx
@@ -35,8 +35,6 @@
 #include "comphelper/processfactory.hxx"
 #include "com/sun/star/i18n/ScriptType.hpp"
 #include "com/sun/star/i18n/DirectionProperty.hpp"
-#include "com/sun/star/rendering/PathCapType.hpp"
-#include "com/sun/star/rendering/PathJoinType.hpp"
 
 #include <string.h>
 
@@ -778,12 +776,11 @@ void DrawXmlOptimizer::visit( DocumentElement& elem, 
const std::list< Element* >
 }
 
 
-
-
 void DrawXmlFinalizer::visit( PolyPolyElement& elem, const std::list< Element* 
>::const_iterator& )
 {
     // xxx TODO copied from DrawElement
     const GraphicsContext& rGC = m_rProcessor.getGraphicsContext(elem.GCId );
+
     PropertyMap aProps;
     aProps[ "style:family" ] = "graphic";
     aProps[ "style:parent-style-name" ] = "standard";
@@ -791,52 +788,29 @@ void DrawXmlFinalizer::visit( PolyPolyElement& elem, 
const std::list< Element* >
     m_rStyleContainer.getStandardStyleId( "graphic" );
 
     PropertyMap aGCProps;
-
-    // TODO(F3): proper dash emulation
-    if( elem.Action & PATH_STROKE )
+    if (elem.Action & PATH_STROKE)
     {
-        aGCProps[ "draw:stroke" ] = rGC.DashArray.empty() ? OUString("solid") 
: OUString("dash");
-        aGCProps[ "svg:stroke-color" ] = getColorString( rGC.LineColor );
-        if( rGC.LineWidth != 0.0 )
-        {
-            ::basegfx::B2DVector aVec(rGC.LineWidth,0);
-            aVec *= rGC.Transformation;
-
-            aVec.setX ( convPx2mmPrec2( aVec.getX() )*100.0 );
-            aVec.setY ( convPx2mmPrec2( aVec.getY() )*100.0 );
-
-            aGCProps[ "svg:stroke-width" ] = OUString::number( 
aVec.getLength() );
-        }
-        OUString strokeLinejoinValue;
-        OUString strokeLinecapValue;
-        switch (rGC.LineJoin)
+        double scale = GetAverageTransformationScale(rGC.Transformation);
+        if (rGC.DashArray.size() < 2)
         {
-        default:
-        case rendering::PathJoinType::MITER:
-            strokeLinejoinValue = "miter";
-            break;
-        case rendering::PathJoinType::ROUND:
-            strokeLinejoinValue = "round";
-            break;
-        case rendering::PathJoinType::BEVEL:
-            strokeLinejoinValue = "bevel";
-            break;
+            aGCProps[ "draw:stroke" ] = "solid";
         }
-        switch (rGC.LineCap)
+        else
         {
-        default:
-        case rendering::PathCapType::BUTT:
-            strokeLinecapValue = "butt";
-            break;
-        case rendering::PathCapType::ROUND:
-            strokeLinecapValue = "round";
-            break;
-        case rendering::PathCapType::SQUARE:
-            strokeLinecapValue = "square";
-            break;
+            PropertyMap props;
+            FillDashStyleProps(props, rGC.DashArray, scale);
+            StyleContainer::Style style("draw:stroke-dash", props);
+
+            aGCProps[ "draw:stroke" ] = "dash";
+            aGCProps[ "draw:stroke-dash" ] =
+                m_rStyleContainer.getStyleName(
+                m_rStyleContainer.getStyleId(style));
         }
-        aGCProps[ "draw:stroke-linejoin" ] = strokeLinejoinValue;
-        aGCProps[ "svg:stroke-linecap" ] = strokeLinecapValue;
+
+        aGCProps[ "svg:stroke-color" ] = getColorString(rGC.LineColor);
+        aGCProps[ "svg:stroke-width" ] = 
convertPixelToUnitString(rGC.LineWidth * scale);
+        aGCProps[ "draw:stroke-linejoin" ] = rGC.GetLineJoinString();
+        aGCProps[ "svg:stroke-linecap" ] = rGC.GetLineCapString();
     }
     else
     {
diff --git a/sdext/source/pdfimport/tree/style.cxx 
b/sdext/source/pdfimport/tree/style.cxx
index d352382..4e91dcf 100644
--- a/sdext/source/pdfimport/tree/style.cxx
+++ b/sdext/source/pdfimport/tree/style.cxx
@@ -191,6 +191,8 @@ void StyleContainer::impl_emitStyle( sal_Int32           
nStyleId,
             PropertyMap aProps( rStyle.Properties );
         if( !rStyle.IsSubStyle )
             aProps[ "style:name" ] = getStyleName( nStyleId );
+        if (rStyle.Name == "draw:stroke-dash")
+            aProps[ "draw:name" ] = aProps[ "style:name" ];
         rContext.rEmitter.beginTag( rStyle.Name.getStr(), aProps );
 
         for( unsigned int n = 0; n < rStyle.SubStyles.size(); ++n )
diff --git a/sdext/source/pdfimport/tree/writertreevisiting.cxx 
b/sdext/source/pdfimport/tree/writertreevisiting.cxx
index c4aeffd..76373cd 100644
--- a/sdext/source/pdfimport/tree/writertreevisiting.cxx
+++ b/sdext/source/pdfimport/tree/writertreevisiting.cxx
@@ -28,8 +28,6 @@
 
 #include "basegfx/polygon/b2dpolypolygontools.hxx"
 #include "basegfx/range/b2drange.hxx"
-#include "com/sun/star/rendering/PathCapType.hpp"
-#include "com/sun/star/rendering/PathJoinType.hpp"
 
 using namespace ::com::sun::star;
 
@@ -845,52 +843,29 @@ void WriterXmlFinalizer::visit( PolyPolyElement& elem, 
const std::list< Element*
     aProps[ "style:family" ] = "graphic";
 
     PropertyMap aGCProps;
-
-    // TODO(F3): proper dash emulation
-    if( elem.Action & PATH_STROKE )
+    if (elem.Action & PATH_STROKE)
     {
-        aGCProps[ "draw:stroke" ] = rGC.DashArray.empty() ? OUString("solid") 
: OUString("dash");
-        aGCProps[ "svg:stroke-color" ] = getColorString( rGC.LineColor );
-        if( rGC.LineWidth != 0.0 )
+        double scale = GetAverageTransformationScale(rGC.Transformation);
+        if (rGC.DashArray.size() < 2)
         {
-            ::basegfx::B2DVector aVec(rGC.LineWidth,0);
-            aVec *= rGC.Transformation;
-
-            aVec.setX ( convPx2mmPrec2( aVec.getX() )*100.0 );
-            aVec.setY ( convPx2mmPrec2( aVec.getY() )*100.0 );
-
-            aGCProps[ "svg:stroke-width" ] = OUString::number( 
aVec.getLength() );
+            aGCProps[ "draw:stroke" ] = "solid";
         }
-        OUString strokeLinejoinValue;
-        OUString strokeLinecapValue;
-        switch (rGC.LineJoin)
-        {
-        default:
-        case rendering::PathJoinType::MITER:
-            strokeLinejoinValue = "miter";
-            break;
-        case rendering::PathJoinType::ROUND:
-            strokeLinejoinValue = "round";
-            break;
-        case rendering::PathJoinType::BEVEL:
-            strokeLinejoinValue = "bevel";
-            break;
-        }
-        switch (rGC.LineCap)
+        else
         {
-        default:
-        case rendering::PathCapType::BUTT:
-            strokeLinecapValue = "butt";
-            break;
-        case rendering::PathCapType::ROUND:
-            strokeLinecapValue = "round";
-            break;
-        case rendering::PathCapType::SQUARE:
-            strokeLinecapValue = "square";
-            break;
+            PropertyMap props;
+            FillDashStyleProps(props, rGC.DashArray, scale);
+            StyleContainer::Style style("draw:stroke-dash", props);
+
+            aGCProps[ "draw:stroke" ] = "dash";
+            aGCProps[ "draw:stroke-dash" ] =
+                m_rStyleContainer.getStyleName(
+                m_rStyleContainer.getStyleId(style));
         }
-        aGCProps[ "draw:stroke-linejoin" ] = strokeLinejoinValue;
-        aGCProps[ "svg:stroke-linecap" ] = strokeLinecapValue;
+
+        aGCProps[ "svg:stroke-color" ] = getColorString(rGC.LineColor);
+        aGCProps[ "svg:stroke-width" ] = 
convertPixelToUnitString(rGC.LineWidth * scale);
+        aGCProps[ "draw:stroke-linejoin" ] = rGC.GetLineJoinString();
+        aGCProps[ "svg:stroke-linecap" ] = rGC.GetLineCapString();
     }
     else
     {
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to