Add PreMultiplyColor()

Add a Skia-only utility function to premultiply FX_ABGR_STRUCT and
similar structs. This will be used in CFX_DIBitmap::Clear(), where the
color parameter is always going to be specified with straight alpha. It
may be used in other places as well, since PDFium internally specifies
FX_ARGB values with straight alpha.

Bug: 42271020
Change-Id: I2fbf694495d78e79c86035c526cbb0ee9630c77f
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/122632
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Tom Sepez <tsepez@google.com>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxge/dib/fx_dib_unittest.cpp b/core/fxge/dib/fx_dib_unittest.cpp
new file mode 100644
index 0000000..6db5793
--- /dev/null
+++ b/core/fxge/dib/fx_dib_unittest.cpp
@@ -0,0 +1,59 @@
+// Copyright 2024 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/fxge/dib/fx_dib.h"
+
+#include <stdint.h>
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+#if defined(PDF_USE_SKIA)
+TEST(PreMultiplyTest, PreMultiplyColor) {
+  FX_ABGR_STRUCT<uint8_t> result = PreMultiplyColor(FX_ABGR_STRUCT<uint8_t>{
+      .alpha = 192, .blue = 0, .green = 255, .red = 100});
+  EXPECT_EQ(192, result.alpha);
+  EXPECT_EQ(0, result.blue);
+  EXPECT_EQ(192, result.green);
+  EXPECT_EQ(75, result.red);
+
+  FX_RGBA_STRUCT<float> result_f = PreMultiplyColor(
+      FX_RGBA_STRUCT<float>{.red = 100, .green = 255, .blue = 0, .alpha = 192});
+  EXPECT_FLOAT_EQ(75.294121f, result_f.red);
+  EXPECT_FLOAT_EQ(192.0f, result_f.green);
+  EXPECT_FLOAT_EQ(0.0f, result_f.blue);
+  EXPECT_FLOAT_EQ(192.0f, result_f.alpha);
+}
+
+TEST(PreMultiplyTest, PreMultiplyColorFullyTransparent) {
+  FX_ABGR_STRUCT<uint8_t> result = PreMultiplyColor(
+      FX_ABGR_STRUCT<uint8_t>{.alpha = 0, .blue = 0, .green = 255, .red = 100});
+  EXPECT_EQ(0, result.alpha);
+  EXPECT_EQ(0, result.blue);
+  EXPECT_EQ(0, result.green);
+  EXPECT_EQ(0, result.red);
+
+  FX_RGBA_STRUCT<float> result_f = PreMultiplyColor(
+      FX_RGBA_STRUCT<float>{.red = 100, .green = 255, .blue = 0, .alpha = 0});
+  EXPECT_FLOAT_EQ(0.0f, result_f.red);
+  EXPECT_FLOAT_EQ(0.0f, result_f.green);
+  EXPECT_FLOAT_EQ(0.0f, result_f.blue);
+  EXPECT_FLOAT_EQ(0.0f, result_f.alpha);
+}
+
+TEST(PreMultiplyTest, PreMultiplyColorFullyOpaque) {
+  FX_ABGR_STRUCT<uint8_t> result = PreMultiplyColor(FX_ABGR_STRUCT<uint8_t>{
+      .alpha = 255, .blue = 0, .green = 255, .red = 100});
+  EXPECT_EQ(255, result.alpha);
+  EXPECT_EQ(0, result.blue);
+  EXPECT_EQ(255, result.green);
+  EXPECT_EQ(100, result.red);
+
+  FX_RGBA_STRUCT<float> result_f = PreMultiplyColor(
+      FX_RGBA_STRUCT<float>{.red = 100, .green = 255, .blue = 0, .alpha = 255});
+  EXPECT_FLOAT_EQ(100.0f, result_f.red);
+  EXPECT_FLOAT_EQ(255.0f, result_f.green);
+  EXPECT_FLOAT_EQ(0.0f, result_f.blue);
+  EXPECT_FLOAT_EQ(255.0f, result_f.alpha);
+}
+#endif  // defined(PDF_USE_SKIA)