summaryrefslogtreecommitdiff
path: root/drawinglayer
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2021-04-30 16:41:19 +0200
committerLuboš Luňák <l.lunak@collabora.com>2021-05-01 00:17:46 +0200
commit565824df07913f47851804daed9efa28a4a95e9d (patch)
treeacfdc44917b4b6a0541c4e3f30c1f579fc92b6a8 /drawinglayer
parent4283fb9d4a6152643364bfe1f98ee1f36aabbb78 (diff)
fix dashed line info conversion for metafile (tdf#136957)
My previous change had two problems: - It didn't handle correctly the case when something repeated, such as dash-dot-dot. - The rounding when setting lengths was a left-over from my first attempt when LineInfo used integers and not floats. Change-Id: I914241590b1ddec22df04c05dfe65e76e921ee52 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114940 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'drawinglayer')
-rw-r--r--drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx91
1 files changed, 59 insertions, 32 deletions
diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
index 0dc0904015f0..8837354fc706 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
@@ -1591,40 +1591,67 @@ void VclMetafileProcessor2D::processPolygonStrokePrimitive2D(
{
aHairLinePolyPolygon.append(rBasePolygon);
}
- else if (rStroke.getDotDashArray().size() == 2)
- {
- aHairLinePolyPolygon.append(rBasePolygon);
- // This will be used by setupStrokeAttributes() in cppcanvas.
- aLineInfo.SetStyle(LineStyle::Dash);
- aLineInfo.SetDashCount(1);
- aLineInfo.SetDashLen(
- basegfx::fround(getTransformedLineWidth(rStroke.getDotDashArray()[0])));
- aLineInfo.SetDistance(
- basegfx::fround(getTransformedLineWidth(rStroke.getDotDashArray()[1])));
- }
- else if (rStroke.getDotDashArray().size() == 4
- && rStroke.getDotDashArray()[1] == rStroke.getDotDashArray()[3])
- {
- aHairLinePolyPolygon.append(rBasePolygon);
- // This will be used by setupStrokeAttributes() in cppcanvas.
- aLineInfo.SetStyle(LineStyle::Dash);
- aLineInfo.SetDashCount(1);
- aLineInfo.SetDashLen(
- basegfx::fround(getTransformedLineWidth(rStroke.getDotDashArray()[0])));
- aLineInfo.SetDistance(
- basegfx::fround(getTransformedLineWidth(rStroke.getDotDashArray()[1])));
- aLineInfo.SetDotCount(1);
- aLineInfo.SetDotLen(
- basegfx::fround(getTransformedLineWidth(rStroke.getDotDashArray()[2])));
- }
else
{
- // LineInfo can hold only limited info about dashing, apply dashing manually
- // if LineInfo cannot describe it. That should not happen though.
- SAL_WARN("drawinglayer", "dotdash array cannot be converted to LineInfo");
- basegfx::utils::applyLineDashing(rBasePolygon, rStroke.getDotDashArray(),
- &aHairLinePolyPolygon, nullptr,
- rStroke.getFullDotDashLen());
+ bool done = false;
+ const std::vector<double>& array = rStroke.getDotDashArray();
+ // The dotdash array should generally have the form
+ // (<dashLen> <distance>)+ (<dotLen> <distance>)*
+ // (where (,),+ and * have their regex meaning).
+ // Find out what the lengths and their counts are.
+ if (!array.empty() && array.size() % 2 == 0)
+ {
+ double dashLen = array[0];
+ double distance = array[1];
+ int dashCount = 1;
+ double dotLen = 0;
+ int dotCount = 0;
+ size_t pos = 2;
+ while (pos + 2 <= array.size())
+ {
+ if (array[pos] != dashLen || array[pos + 1] != distance)
+ break;
+ ++dashCount;
+ pos += 2;
+ }
+ if (pos + 2 <= array.size() && array[pos + 1] == distance)
+ {
+ dotLen = array[pos];
+ ++dotCount;
+ pos += 2;
+ while (pos + 2 <= array.size())
+ {
+ if (array[pos] != dotLen || array[pos + 1] != distance)
+ break;
+ ++dotCount;
+ pos += 2;
+ }
+ }
+ if (array.size() == pos)
+ {
+ aHairLinePolyPolygon.append(rBasePolygon);
+ // This will be used by setupStrokeAttributes() in cppcanvas.
+ aLineInfo.SetStyle(LineStyle::Dash);
+ aLineInfo.SetDashCount(dashCount);
+ aLineInfo.SetDashLen(getTransformedLineWidth(dashLen));
+ aLineInfo.SetDistance(getTransformedLineWidth(distance));
+ if (dotCount != 0)
+ {
+ aLineInfo.SetDotCount(dotCount);
+ aLineInfo.SetDotLen(getTransformedLineWidth(dotLen));
+ }
+ done = true;
+ }
+ }
+ if (!done)
+ {
+ // LineInfo can hold only limited info about dashing, apply dashing manually
+ // if LineInfo cannot describe it. That should not happen though.
+ SAL_WARN("drawinglayer", "dotdash array cannot be converted to LineInfo");
+ basegfx::utils::applyLineDashing(rBasePolygon, rStroke.getDotDashArray(),
+ &aHairLinePolyPolygon, nullptr,
+ rStroke.getFullDotDashLen());
+ }
}
aHairLinePolyPolygon.transform(maCurrentTransformation);