[Skia] Handle odd-sized dashed line arrays correctly An odd-sized dashed line array should alternate on-offs after the first passthrough. For example, [2, 1, 3] with a phase of 0 should look like: 2 on, 1 off, 3 on, 2 off, 1 on, 3 off, 2 on, etc. SkDashPathEffect only takes even-sized dash vectors. To work around this, repeat the dashed line array in SetupStrokePaint(), which should have the same effect as an odd-sized dashed line array. E.g. [2, 1, 3] becomes [2, 1, 3, 2, 1, 3]. Since on-offs alternate, update SetupStrokePaint() so that the same transformation is applied to each value in the dash array, rather than two separate transformations for dashes and gaps. Test expectations updated at https://pdfium-review.googlesource.com/c/pdfium_tests/+/138890. Bug: 370546365 Change-Id: I2030bef3ae792375b89c312cc9b84502f2179558 Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/138870 Commit-Queue: Lei Zhang <thestig@chromium.org> Auto-Submit: Andy Phan <andyphan@chromium.org> Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/DEPS b/DEPS index bbc2d5e..887e2e8 100644 --- a/DEPS +++ b/DEPS
@@ -197,7 +197,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling pdfium_tests # and whatever else without interference from each other. - 'pdfium_tests_revision': '2fb8c36c11d681f042547aa8e84757dde7b0b11e', + 'pdfium_tests_revision': 'fc9585fb46b615ad70e7ed59529941ceb31c3e94', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling result_adapter_revision # and whatever else without interference from each other.
diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp index 6529997..fea8e30 100644 --- a/core/fxge/skia/fx_skia_device.cpp +++ b/core/fxge/skia/fx_skia_device.cpp
@@ -569,18 +569,21 @@ device_units[1].length())); const std::vector<float>& dash_array = stroke_options->dash_array(); if (!dash_array.empty()) { - size_t count = (dash_array.size() + 1) / 2; - DataVector<float> intervals(count * 2); - // Set dash pattern - for (size_t i = 0; i < count; i++) { - float on = dash_array[i * 2]; - if (on <= 0.000001f) { - on = 0.1f; + // `SkDashPathEffect` only takes even-sized interval arrays. Support + // odd-sized arrays by just doubling the size of `dash_array` and repeating + // its contents, e.g. [2, 1, 3] becomes [2, 1, 3, 2, 1, 3]. + size_t count = dash_array.size(); + bool is_even_sized = count % 2 == 0; + DataVector<float> intervals; + intervals.reserve(is_even_sized ? count : count * 2); + for (float dash_len : dash_array) { + if (dash_len <= 0.000001f) { + dash_len = 0.1f; } - float off = i * 2 + 1 == dash_array.size() ? on : dash_array[i * 2 + 1]; - off = std::max(off, 0.0f); - intervals[i * 2] = on; - intervals[i * 2 + 1] = off; + intervals.push_back(dash_len); + } + if (!is_even_sized) { + intervals.insert(intervals.end(), intervals.begin(), intervals.end()); } stroke_paint->setPathEffect( SkDashPathEffect::Make(intervals, stroke_options->dash_phase()));
diff --git a/testing/resources/pixel/dashed_lines_expected_skia.pdf.0.png b/testing/resources/pixel/dashed_lines_expected_skia.pdf.0.png index 1fc9c4d..e2a0657 100644 --- a/testing/resources/pixel/dashed_lines_expected_skia.pdf.0.png +++ b/testing/resources/pixel/dashed_lines_expected_skia.pdf.0.png Binary files differ