[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