Add GDI renderer support to test_runner.py

Adds support for running test_runner.py tests with --use-renderer=gdi.

Bug: pdfium:2054
Change-Id: Id5533a89d0ac39415392cee234f0626fb7fef08a
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/108931
Commit-Queue: K. Moon <kmoon@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/samples/pdfium_test.cc b/samples/pdfium_test.cc
index f25ebfc..4ff72ce 100644
--- a/samples/pdfium_test.cc
+++ b/samples/pdfium_test.cc
@@ -1524,6 +1524,9 @@
 #ifdef PDF_ENABLE_SKIA
   append_config("SKIA");
 #endif
+#ifdef _WIN32
+  append_config("GDI");
+#endif
   printf("%s\n", config.c_str());
 }
 
diff --git a/testing/SUPPRESSIONS b/testing/SUPPRESSIONS
index 222099a..17605b2 100644
--- a/testing/SUPPRESSIONS
+++ b/testing/SUPPRESSIONS
@@ -10,7 +10,7 @@
 # Column 1: platform: *, win, mac, linux
 # Column 2: v8 support: *, nov8, v8
 # Column 3: xfa support: *, noxfa, xfa
-# Column 4: rendering support: *, agg, skia
+# Column 4: rendering support: *, agg, gdi, skia
 #
 # All columns on a line on a line must match, but filenames may be repeated
 # on subsequent lines to suppress more cases.  Within each column, any one of
diff --git a/testing/SUPPRESSIONS_EXACT_MATCHING b/testing/SUPPRESSIONS_EXACT_MATCHING
index 7c260d1..b9734d9 100644
--- a/testing/SUPPRESSIONS_EXACT_MATCHING
+++ b/testing/SUPPRESSIONS_EXACT_MATCHING
@@ -10,7 +10,7 @@
 # Column 1: platform: *, win, mac, linux
 # Column 2: v8 support: *, nov8, v8
 # Column 3: xfa support: *, noxfa, xfa
-# Column 4: rendering support: *, agg, skia
+# Column 4: rendering support: *, agg, gdi, skia
 #
 # All columns on a line on a line must match, but filenames may be repeated
 # on subsequent lines to suppress more cases.  Within each column, any one of
diff --git a/testing/SUPPRESSIONS_IMAGE_DIFF b/testing/SUPPRESSIONS_IMAGE_DIFF
index e501756..e7ecd21 100644
--- a/testing/SUPPRESSIONS_IMAGE_DIFF
+++ b/testing/SUPPRESSIONS_IMAGE_DIFF
@@ -10,7 +10,7 @@
 # Column 1: platform: *, win, mac, linux
 # Column 2: v8 support: *, nov8, v8
 # Column 3: xfa support: *, noxfa, xfa
-# Column 4: rendering support: *, agg, skia
+# Column 4: rendering support: *, agg, gdi, skia
 #
 # All columns on a line on a line must match, but filenames may be repeated
 # on subsequent lines to suppress more cases.  Within each column, any one of
diff --git a/testing/tools/pngdiffer.py b/testing/tools/pngdiffer.py
index 2044a34..ceb4022 100755
--- a/testing/tools/pngdiffer.py
+++ b/testing/tools/pngdiffer.py
@@ -15,8 +15,11 @@
 
 _PNG_OPTIMIZER = 'optipng'
 
+# Each suffix order acts like a path along a tree, with the leaves being the
+# most specific, and the root being the least specific.
 _COMMON_SUFFIX_ORDER = ('_{os}', '')
 _AGG_SUFFIX_ORDER = ('_agg_{os}', '_agg') + _COMMON_SUFFIX_ORDER
+_GDI_SUFFIX_ORDER = ('_gdi_{os}', '_gdi') + _COMMON_SUFFIX_ORDER
 _SKIA_SUFFIX_ORDER = ('_skia_{os}', '_skia') + _COMMON_SUFFIX_ORDER
 
 
@@ -37,14 +40,19 @@
 
 class PNGDiffer():
 
-  def __init__(self, finder, features, reverse_byte_order):
+  def __init__(self, finder, reverse_byte_order, rendering_option):
     self.pdfium_diff_path = finder.ExecutablePath('pdfium_diff')
     self.os_name = finder.os_name
     self.reverse_byte_order = reverse_byte_order
-    if 'SKIA' in features:
+
+    if rendering_option == 'agg':
+      self.suffix_order = _AGG_SUFFIX_ORDER
+    elif rendering_option == 'gdi':
+      self.suffix_order = _GDI_SUFFIX_ORDER
+    elif rendering_option == 'skia':
       self.suffix_order = _SKIA_SUFFIX_ORDER
     else:
-      self.suffix_order = _AGG_SUFFIX_ORDER
+      raise ValueError(f'rendering_option={rendering_option}')
 
   def CheckMissingTools(self, regenerate_expected):
     if regenerate_expected and not shutil.which(_PNG_OPTIMIZER):
diff --git a/testing/tools/suppressor.py b/testing/tools/suppressor.py
index 989f4dd..6fea735 100755
--- a/testing/tools/suppressor.py
+++ b/testing/tools/suppressor.py
@@ -11,10 +11,11 @@
 
 class Suppressor:
 
-  def __init__(self, finder, features, js_disabled, xfa_disabled):
+  def __init__(self, finder, features, js_disabled, xfa_disabled,
+               rendering_option):
     self.has_v8 = not js_disabled and 'V8' in features
     self.has_xfa = not js_disabled and not xfa_disabled and 'XFA' in features
-    self.has_skia = 'SKIA' in features
+    self.rendering_option = rendering_option
     self.suppression_set = self._LoadSuppressedSet('SUPPRESSIONS', finder)
     self.image_suppression_set = self._LoadSuppressedSet(
         'SUPPRESSIONS_IMAGE_DIFF', finder)
@@ -24,11 +25,10 @@
   def _LoadSuppressedSet(self, suppressions_filename, finder):
     v8_option = "v8" if self.has_v8 else "nov8"
     xfa_option = "xfa" if self.has_xfa else "noxfa"
-    rendering_option = "skia" if self.has_skia else "agg"
     with open(os.path.join(finder.TestingDir(), suppressions_filename)) as f:
       return set(
-          self._FilterSuppressions(common.os_name(), v8_option,
-                                   xfa_option, rendering_option,
+          self._FilterSuppressions(common.os_name(), v8_option, xfa_option,
+                                   self.rendering_option,
                                    self._ExtractSuppressions(f)))
 
   def _ExtractSuppressions(self, f):
diff --git a/testing/tools/test_runner.py b/testing/tools/test_runner.py
index 1920299..a4e3dd9 100644
--- a/testing/tools/test_runner.py
+++ b/testing/tools/test_runner.py
@@ -223,7 +223,7 @@
 
     parser.add_argument(
         '--use-renderer',
-        choices=('agg', 'skia'),
+        choices=('agg', 'gdi', 'skia'),
         help='Forces the renderer to use.')
 
     parser.add_argument(
@@ -428,6 +428,7 @@
     enforce_expected_images: Whether to enforce expected images.
     options: The dictionary of command line options.
     features: The set of features supported by `pdfium_test`.
+    rendering_option: The renderer to use (agg, gdi, or skia).
   """
   test_dir: str
   test_type: str
@@ -435,6 +436,7 @@
   enforce_expected_images: bool = False
   options: dict = None
   features: set = None
+  rendering_option: str = None
 
   def NewFinder(self):
     return common.DirectoryFinder(self.options.build_dir)
@@ -447,11 +449,21 @@
                                      timeout=TEST_TIMEOUT)
     self.features = set(output.decode('utf-8').strip().split(','))
 
+    if 'SKIA' in self.features:
+      self.rendering_option = 'skia'
+    else:
+      self.rendering_option = 'agg'
+
     if self.options.use_renderer == 'agg':
-      self.features.discard('SKIA')
+      self.rendering_option = 'agg'
+    elif self.options.use_renderer == 'gdi':
+      if 'GDI' not in self.features:
+        return 'pdfium_test does not support the GDI renderer'
+      self.rendering_option = 'gdi'
     elif self.options.use_renderer == 'skia':
       if 'SKIA' not in self.features:
         return 'pdfium_test does not support the Skia renderer'
+      self.rendering_option = 'skia'
 
     return None
 
@@ -479,9 +491,10 @@
 
     self.test_suppressor = suppressor.Suppressor(
         finder, self.features, self.options.disable_javascript,
-        self.options.disable_xfa)
-    self.image_differ = pngdiffer.PNGDiffer(finder, self.features,
-                                            self.options.reverse_byte_order)
+        self.options.disable_xfa, config.rendering_option)
+    self.image_differ = pngdiffer.PNGDiffer(finder,
+                                            self.options.reverse_byte_order,
+                                            config.rendering_option)
 
     self.process_name = multiprocessing.current_process().name
     self.skia_tester = None