Make fixed-point arithmetic in CStretchEngine more obvious.

In particular, allow adjusting the fractional bits with one constant.
However, I expect there may be an overflow at line 612 if this is
made larger. Theoretically, we should be able to use up to 24 bits
if we move to unsigned types and watch for overflows.

Change-Id: I9a4210f15c362801c51b619e790bc152a8282b51
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/81751
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxge/dib/cstretchengine.cpp b/core/fxge/dib/cstretchengine.cpp
index 3fe7f3e..ef39778 100644
--- a/core/fxge/dib/cstretchengine.cpp
+++ b/core/fxge/dib/cstretchengine.cpp
@@ -19,6 +19,9 @@
 
 namespace {
 
+constexpr uint32_t kFixedPointBits = 16;
+constexpr uint32_t kFixedPointOne = 1 << kFixedPointBits;
+
 int GetPitchRoundUpTo4Bytes(int bits_per_pixel) {
   return (bits_per_pixel + 31) / 32 * 4;
 }
@@ -81,19 +84,20 @@
         pixel_weights.m_SrcStart = std::max(pixel_weights.m_SrcStart, src_min);
         pixel_weights.m_SrcEnd = std::min(pixel_weights.m_SrcEnd, src_max - 1);
         if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) {
-          pixel_weights.m_Weights[0] = 65536;
+          pixel_weights.m_Weights[0] = kFixedPointOne;
         } else {
           pixel_weights.m_Weights[1] =
               FXSYS_roundf(static_cast<float>(
                                src_pos - pixel_weights.m_SrcStart - 1.0f / 2) *
-                           65536);
-          pixel_weights.m_Weights[0] = 65536 - pixel_weights.m_Weights[1];
+                           kFixedPointOne);
+          pixel_weights.m_Weights[0] =
+              kFixedPointOne - pixel_weights.m_Weights[1];
         }
       } else {
         int pixel_pos = static_cast<int>(floor(static_cast<float>(src_pos)));
         pixel_weights.m_SrcStart = std::max(pixel_pos, src_min);
         pixel_weights.m_SrcEnd = std::min(pixel_pos, src_max - 1);
-        pixel_weights.m_Weights[0] = 65536;
+        pixel_weights.m_Weights[0] = kFixedPointOne;
       }
     }
     return true;
@@ -131,7 +135,7 @@
       if (idx >= GetPixelWeightCount())
         return false;
 
-      pixel_weights.m_Weights[idx] = FXSYS_roundf(weight * 65536);
+      pixel_weights.m_Weights[idx] = FXSYS_roundf(weight * kFixedPointOne);
     }
   }
   return true;
@@ -318,7 +322,7 @@
             if (src_scan[j / 8] & (1 << (7 - j % 8)))
               dest_a += pixel_weight * 255;
           }
-          *dest_scan++ = static_cast<uint8_t>(dest_a >> 16);
+          *dest_scan++ = static_cast<uint8_t>(dest_a >> kFixedPointBits);
         }
         break;
       }
@@ -334,7 +338,7 @@
             int pixel_weight = *pWeight;
             dest_a += pixel_weight * src_scan[j];
           }
-          *dest_scan++ = static_cast<uint8_t>(dest_a >> 16);
+          *dest_scan++ = static_cast<uint8_t>(dest_a >> kFixedPointBits);
         }
         break;
       }
@@ -353,8 +357,9 @@
             dest_r += pixel_weight * src_scan[j];
             dest_a += pixel_weight;
           }
-          *dest_scan++ = static_cast<uint8_t>(dest_r >> 16);
-          *dest_scan_mask++ = static_cast<uint8_t>((dest_a * 255) >> 16);
+          *dest_scan++ = static_cast<uint8_t>(dest_r >> kFixedPointBits);
+          *dest_scan_mask++ =
+              static_cast<uint8_t>((dest_a * 255) >> kFixedPointBits);
         }
         break;
       }
@@ -381,9 +386,9 @@
               dest_r += pixel_weight * static_cast<uint8_t>(argb >> 8);
             }
           }
-          *dest_scan++ = static_cast<uint8_t>(dest_b >> 16);
-          *dest_scan++ = static_cast<uint8_t>(dest_g >> 16);
-          *dest_scan++ = static_cast<uint8_t>(dest_r >> 16);
+          *dest_scan++ = static_cast<uint8_t>(dest_b >> kFixedPointBits);
+          *dest_scan++ = static_cast<uint8_t>(dest_g >> kFixedPointBits);
+          *dest_scan++ = static_cast<uint8_t>(dest_r >> kFixedPointBits);
         }
         break;
       }
@@ -407,10 +412,11 @@
             dest_r += pixel_weight * static_cast<uint8_t>(argb >> 8);
             dest_a += pixel_weight;
           }
-          *dest_scan++ = static_cast<uint8_t>(dest_b >> 16);
-          *dest_scan++ = static_cast<uint8_t>(dest_g >> 16);
-          *dest_scan++ = static_cast<uint8_t>(dest_r >> 16);
-          *dest_scan_mask++ = static_cast<uint8_t>((dest_a * 255) >> 16);
+          *dest_scan++ = static_cast<uint8_t>(dest_b >> kFixedPointBits);
+          *dest_scan++ = static_cast<uint8_t>(dest_g >> kFixedPointBits);
+          *dest_scan++ = static_cast<uint8_t>(dest_r >> kFixedPointBits);
+          *dest_scan_mask++ =
+              static_cast<uint8_t>((dest_a * 255) >> kFixedPointBits);
         }
         break;
       }
@@ -431,9 +437,9 @@
             dest_g += pixel_weight * (*src_pixel++);
             dest_r += pixel_weight * (*src_pixel);
           }
-          *dest_scan++ = static_cast<uint8_t>(dest_b >> 16);
-          *dest_scan++ = static_cast<uint8_t>(dest_g >> 16);
-          *dest_scan++ = static_cast<uint8_t>(dest_r >> 16);
+          *dest_scan++ = static_cast<uint8_t>(dest_b >> kFixedPointBits);
+          *dest_scan++ = static_cast<uint8_t>(dest_g >> kFixedPointBits);
+          *dest_scan++ = static_cast<uint8_t>(dest_r >> kFixedPointBits);
           dest_scan += Bpp - 3;
         }
         break;
@@ -462,13 +468,15 @@
             dest_r += pixel_weight * (*src_pixel);
             dest_a += pixel_weight;
           }
-          *dest_scan++ = static_cast<uint8_t>(dest_b >> 16);
-          *dest_scan++ = static_cast<uint8_t>(dest_g >> 16);
-          *dest_scan++ = static_cast<uint8_t>(dest_r >> 16);
+          *dest_scan++ = static_cast<uint8_t>(dest_b >> kFixedPointBits);
+          *dest_scan++ = static_cast<uint8_t>(dest_g >> kFixedPointBits);
+          *dest_scan++ = static_cast<uint8_t>(dest_r >> kFixedPointBits);
           if (m_DestFormat == FXDIB_Format::kArgb)
-            *dest_scan = static_cast<uint8_t>((dest_a * 255) >> 16);
+            *dest_scan =
+                static_cast<uint8_t>((dest_a * 255) >> kFixedPointBits);
           if (dest_scan_mask)
-            *dest_scan_mask++ = static_cast<uint8_t>((dest_a * 255) >> 16);
+            *dest_scan_mask++ =
+                static_cast<uint8_t>((dest_a * 255) >> kFixedPointBits);
           dest_scan += Bpp - 3;
         }
         break;
@@ -512,7 +520,7 @@
             dest_a +=
                 pixel_weight * src_scan[(j - m_SrcClip.top) * m_InterPitch];
           }
-          *dest_scan = static_cast<uint8_t>(dest_a >> 16);
+          *dest_scan = static_cast<uint8_t>(dest_a >> kFixedPointBits);
           dest_scan += DestBpp;
         }
         break;
@@ -536,9 +544,9 @@
             dest_a += pixel_weight *
                       src_scan_mask[(j - m_SrcClip.top) * m_ExtraMaskPitch];
           }
-          *dest_scan = static_cast<uint8_t>(dest_k >> 16);
+          *dest_scan = static_cast<uint8_t>(dest_k >> kFixedPointBits);
           dest_scan += DestBpp;
-          *dest_scan_mask++ = static_cast<uint8_t>(dest_a >> 16);
+          *dest_scan_mask++ = static_cast<uint8_t>(dest_a >> kFixedPointBits);
         }
         break;
       }
@@ -562,9 +570,9 @@
             dest_g += pixel_weight * (*src_pixel++);
             dest_r += pixel_weight * (*src_pixel);
           }
-          dest_scan[0] = static_cast<uint8_t>(dest_b >> 16);
-          dest_scan[1] = static_cast<uint8_t>(dest_g >> 16);
-          dest_scan[2] = static_cast<uint8_t>(dest_r >> 16);
+          dest_scan[0] = static_cast<uint8_t>(dest_b >> kFixedPointBits);
+          dest_scan[1] = static_cast<uint8_t>(dest_g >> kFixedPointBits);
+          dest_scan[2] = static_cast<uint8_t>(dest_r >> kFixedPointBits);
           dest_scan += DestBpp;
         }
         break;
@@ -609,9 +617,9 @@
             dest_scan[2] = pdfium::clamp(r, 0, 255);
           }
           if (m_DestFormat == FXDIB_Format::kArgb)
-            dest_scan[3] = static_cast<uint8_t>((dest_a) >> 16);
+            dest_scan[3] = static_cast<uint8_t>((dest_a) >> kFixedPointBits);
           else
-            *dest_scan_mask = static_cast<uint8_t>((dest_a) >> 16);
+            *dest_scan_mask = static_cast<uint8_t>((dest_a) >> kFixedPointBits);
           dest_scan += DestBpp;
           if (dest_scan_mask)
             dest_scan_mask++;