summaryrefslogtreecommitdiff
path: root/sdext
diff options
context:
space:
mode:
authorVort <vvort@yandex.ru>2014-05-04 08:49:18 +0300
committerCaolán McNamara <caolanm@redhat.com>2014-05-06 15:07:59 +0000
commitb27fca822cd6f40c8a7e56fe56fdf76bdc0dd159 (patch)
treec2fab90b9e46d9e502ef8e8337e519e562dfc171 /sdext
parentbb2d5c40e48d899bc39a18e6e038e067f6b9418b (diff)
fdo#78241 PDF Import: add dashes support
Change-Id: Ifd9fbce44c7d18114d5be466bfb9d92192573205 Reviewed-on: https://gerrit.libreoffice.org/9246 Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'sdext')
-rw-r--r--sdext/source/pdfimport/inc/pdfihelper.hxx33
-rw-r--r--sdext/source/pdfimport/misc/pdfihelper.cxx53
-rw-r--r--sdext/source/pdfimport/tree/drawtreevisiting.cxx64
-rw-r--r--sdext/source/pdfimport/tree/style.cxx2
-rw-r--r--sdext/source/pdfimport/tree/writertreevisiting.cxx61
5 files changed, 125 insertions, 88 deletions
diff --git a/sdext/source/pdfimport/inc/pdfihelper.hxx b/sdext/source/pdfimport/inc/pdfihelper.hxx
index 2478a96b8e8c..de589a6cefc7 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 8204ad3a6fc8..862f11b5989f 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 acf9ff760fb6..49c1959041c7 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 d3523828d784..4e91dcf26a8c 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 c4aeffd371ad..76373cd58972 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
{