diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2021-04-30 16:41:19 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2021-05-01 00:17:46 +0200 |
commit | 565824df07913f47851804daed9efa28a4a95e9d (patch) | |
tree | acfdc44917b4b6a0541c4e3f30c1f579fc92b6a8 /drawinglayer | |
parent | 4283fb9d4a6152643364bfe1f98ee1f36aabbb78 (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.cxx | 91 |
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); |