Skip to content

Sync S11: merge upstream PDFium up to 7c55203ed (Oct 15 2026) - #78

Merged
bobsingor merged 38 commits into
embedpdf/mainfrom
embedpdf/sync/7c55203ed
Oct 17, 2026
Merged

bobsingor merged 38 commits into
embedpdf/mainfrom
embedpdf/sync/7c55203ed

Conversation

@bobsingor

Copy link
Copy Markdown
Contributor

No description provided.

leizleiz and others added 30 commits October 12, 2026 09:56
Make it more obvious the code is instantiating a null FooPtr.

Change-Id: Ief54445d91ecc0b90a65009429289455ff1c5bab
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160490
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Avoid manually reimplementing it.

Change-Id: I3a5510221a3ee1575e994aacec42d75f7cc6b221
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160491
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Adding arbitrary string data to the ByteStringPool from CPDF_String is
unlikely to generate much data sharing. Instead, only use ByteStringPool
for CPDF_Name, where values like "Type" and "Page" are often repeated.

Change-Id: I261b16b93a9a180c86e6c78b1dfd92a5d7bd1097
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160492
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Per recommendations in Chromium's base/containers/README.md, switch from
std::unordered_set to absl::flat_hash_set.

Change-Id: I0e4dfeea9fe888b0ea2765afa42d165bc69e2e4f
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160493
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
When PDF_USE_LIBYUV is enabled, accelerate lossless pixel format
conversions, alpha plane extraction/injection, horizontal mirroring, and
90/270-degree rotation / transposition in CFX_DIBBase and CFX_DIBitmap:

- ConvertBuffer_RgbToArgbPremul, CFX_DIBitmap::ConvertFormat (kBgr ->
  kBgra), and 24-bpp CFX_DIBBase::RealizeSkImage: use
  libyuv::RGB24ToARGB.
- ConvertBuffer_32bppRgbToRgb24: use libyuv::ARGBToRGB24.
- CFX_DIBBase::CloneAlphaMask: use libyuv::ARGBExtractAlpha.
- CFX_DIBitmap::MultiplyAlphaMask (kBgrx): use libyuv::ARGBCopyYToAlpha.
- CFX_DIBBase::FlipImage: use libyuv::MirrorPlane, libyuv::RGB24Mirror,
  and libyuv::ARGBMirror.
- CFX_DIBBase::SwapXY: use libyuv::RotatePlane90,
  libyuv::RotatePlane270, libyuv::TransposePlane, and libyuv::ARGBRotate
  for 8-bpp and 32-bpp bitmaps via RealizeIfNeeded().

When the source bitmap has a contiguous buffer, invoke the full 2D
libyuv plane functions directly instead of row-by-row.

Speedup vs Before (1275x1650, US Letter 150 DPI):
| Function         | Zen 5  | GNR    | Grace  | Wasm   | RVV    |
|------------------|--------|--------|--------|--------|--------|
| RGB24ToARGB      |  6.08x |  2.53x |  5.65x |  5.54x | 31.04x |
| ARGBToRGB24      |  5.88x |  1.98x |  2.35x |  1.55x | 28.07x |
| ARGBExtractAlpha |  5.95x |  1.90x |  4.13x |  4.33x | 17.05x |
| ARGBCopyYToAlpha |  7.61x |  3.02x |  4.71x |  3.28x |  7.22x |
| MirrorPlane      |  9.59x |  5.28x |  5.84x |  6.04x |  1.33x |
| RGB24Mirror      |  8.32x |  3.02x |  5.40x |  4.53x |  1.00x |
| ARGBMirror       |  4.17x |  1.33x |  2.57x |  3.20x | 21.06x |
| RotatePlane90    | 10.86x |  6.60x |  7.23x |  8.50x |  1.84x |
| RotatePlane270   | 10.75x |  6.59x |  6.97x |  9.31x |  1.84x |
| TransposePlane   | 10.92x |  6.53x |  7.13x |  8.64x |  1.84x |
| ARGBRotate       |  5.40x |  3.01x |  1.65x |  2.74x | 13.24x |

(Zen 5: AMD EPYC Turin AVX-512; GNR: Intel Granite Rapids AVX-512;
Grace: NVIDIA Grace Neoverse V2 SVE2; Wasm: V8 SIMD128; RVV: Coral NPU)

Bug: 42271060, 549230311
Change-Id: I223e13be29cb4546c7d0e53c9dda340dc4375944
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160093
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Introduce EmbedderTest::CompareDisplayList() and helper functions to
compare rendered display lists against expectation files.

Add VerifySavedRenderingWithDisplayList() and
VerifySavedDocumentWithDisplayList() to support testing saved document
rendering with display lists.

Migrate FPDFViewEmbedderTest.RenderPageToDisplayList to use
CompareDisplayList() with rectangles_expected.dump.txt instead of an
inline string literal.

Change-Id: Ie055ae896d535ff87d1894ddc871b3b81eba87b2
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160550
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Add support for an optional 4th parameter to the fuzzy action in
SUPPRESSIONS, allowing tests to specify an SSIM threshold in [0.0, 1.0].

Update Suppressor._ParseFuzzyAction to accept up to 4 parameters and
validate that the SSIM threshold does not exceed 1.0.

Update PNGDiffer._ParseTolerances to extract the SSIM threshold,
defaulting to 1.0. In PNGDiffer.EvaluateMatch, accept comparisons if
either the existing MSE criteria pass or the mean SSIM strictly exceeds
the configured threshold. Defaulting to 1.0 preserves existing behavior
since mean SSIM cannot exceed 1.0.

Change-Id: Icf84478c7c825c4c49c01a3c21168f991ea8879d
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160651
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Add unit test coverage for CFX_DIBBase::TransformTo() in
cfx_dibbase_unittest.cpp, testing empty output bounds, 8-bit mask
rotation/scaling, and BGRA scaling/translation.

TAG=agy
CONV=913b2a22-b8f8-4d2f-a2ad-8d7cc152a129

Change-Id: I51272780d37aae5361e5439cda7de2bd996e6b7f
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160611
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Add unit test coverage for CFX_DIBBase::StretchTo() in
cfx_dibbase_unittest.cpp, testing empty output bounds, 8-bit mask
stretching with horizontal flipping and clipping, 8-bit grayscale
stretching with vertical flipping, and BGRA stretching.

TAG=agy
CONV=913b2a22-b8f8-4d2f-a2ad-8d7cc152a129

Change-Id: Ie252bbe08915d93d136dd154b6560893287b2557
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160630
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
For instance, pdf_enable_fontations and pdf_enable_freetype blocks now
live closer to each other.

Change-Id: Id85bfeeed07033916ee5de8c7eabd3733bb1bc8d
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160650
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Combine columns 2 (V8 support) and 3 (XFA support) into a single engine
column (column 2) accepting nov8, v8, and xfa.

Because XFA requires V8, the combination nov8 with XFA is impossible,
and nov8 without XFA is redundant with nov8. Combining these into a
single 3-state engine column simplifies the suppression table from
7 columns to 6 columns.

Add convert_suppressions.py to perform the transformation on
SUPPRESSIONS.

Update Suppressor._VALID_COLUMN_VALUES, _SuppressionSpecificity, and
_MatchSuppression to match against the unified engine column.

Change-Id: Ib4a892f2a56a9dc26e5a860bb67410a0051a093b
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160670
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Add some TODOs as a first step towards reverting a behavior change
pdfium-review.googlesource.com/c/80912 made. When a path only forms 3
sides of a rectangle and it has not been closed, that should not count
as a rectangle.

Bug: 42270691, 572902676
Change-Id: I5cac1867a77b7dbb351d50f3d1df5fee78e1cac6
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160750
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Andy Phan <andyphan@chromium.org>
Revert a behavior change pdfium-review.googlesource.com/c/80912 made,
since a path that only forms 3 sides of a rectangle and has not been
closed is not a rectangle.

Bug: 42270691, 572902676
Change-Id: I31da35b950e281f0815bfb17b40befd14f21b5cb
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160673
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Andy Phan <andyphan@chromium.org>
Convert ByteStringPool into an interface with ByteStringPool::Create()
and a pure virtual Intern() method, and move the absl::flat_hash_set
implementation into ByteStringPoolImpl in bytestring_pool.cpp. This
avoids exposing absl/container/flat_hash_set.h in bytestring_pool.h.
Since bytestring_pool.h gets transitively included in many translation
units, explosing flat_hash_set.h increases the Chromium compile size by
~450 MB, as seen on crrev.com/c/8563220.

TAG=agy
CONV=9d52233e-f437-4c0d-acb6-07f402d6540c

Change-Id: Iaecae19ee53ce97e57e793f4962c2e8865b1a295
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160690
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
CFX_Path::IsRect(), GetRect(), and GetRectOppositeCorner() recognize
both 4-point and 5-point rectangles, but PathPointsNeedNormalization()
and GetNormalizedPoints() currently only normalize paths that have more
than 5 points and repeat the first point at the end. As a result,
4-point rectangles with duplicate or collinear edge points (such as
paths closed with CFX_Path::ClosePath() instead of repeating the start
point) are not recognized as rectangles.

Add/update tests in cpdf_pagecontentgenerator_unittest.cpp and
cfx_path_unittest.cpp to document the current behavior, along with TODOs
to fix this. In particular, add one more scenario in
CFXPath.FivePointRect, and remove the identical scenario from
CFXPath.NotRect.

TAG=agy
CONV=e2fb55f5-ba6e-4820-9194-44fb5bf14b16

Bug: 572902676
Change-Id: Ife1104f4417a9f9e9a612f856e31848806cfa7d7
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160710
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Andy Phan <andyphan@chromium.org>
CFX_Path::IsRect(), GetRect(), and GetRectOppositeCorner() recognize
both 4-point rectangles (where the start point is not repeated at the
end) and 5-point rectangles (where the start point is repeated at the
end). However, PathPointsNeedNormalization() and GetNormalizedPoints()
only normalized paths with more than 5 points that repeated the start
point at the end.

As a result, 4-point rectangles with duplicate or collinear edge points,
such as paths closed via CFX_Path::ClosePath() / FPDFPath_Close(), were
not recognized as rectangles in memory, even though saving and reloading
the PDF via CPDF_StreamContentParser::Handle_ClosePath() appended the
start point and turned them into rectangles.

Update PathPointsNeedNormalization() to also normalize 5-point paths
where the first and last points differ, and update GetNormalizedPoints()
to normalize paths with differing first and last points to 4 points
while preserving `close_figure_` when deleting a final closing duplicate
or collinear point.

TAG=agy
CONV=e2fb55f5-ba6e-4820-9194-44fb5bf14b16

Bug: 572902676
Change-Id: Ie01ae75c1441666bd488104716f8a08804361684
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160711
Reviewed-by: Andy Phan <andyphan@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
In CPDF_ClipPath::AppendPathWithAutoMerge() and
CPDF_ContentParser::CheckClip(), use GetRectOppositeCorner() and avoid
assuming the point at index 2 is always the opposite corner. After this,
CPDF_Path::IsRect() is dead code, so delete it.

Change-Id: Id2ad3fc4e7d2e7b782bedad56946f91f522608fd
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160770
Reviewed-by: Andy Phan <andyphan@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Prevent a (somewhat) misbehaving embedder from tearing down the
runtime while a callback is still in-flight.

Bug: 572237007
Change-Id: I003a6b67703305c465a2ed0845f4274df93ed5af
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160614
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit 21e954b changed CFX_CSSSyntaxParser::GetCurrentString() to
return a string view instead of taking an out-parameter length, leaving
`iLen2` in CFX_CSSStyleSelector::AppendInlineStyle() and `iValueLen` in
CFX_CSSStyleSheet::LoadStyleRule() permanently zero.

Replace the stale length checks with !wsName.IsEmpty() so custom CSS
properties reach CFX_CSSDeclaration::AddProperty().

Update CFX_CSSDeclaration::empty() to check both properties_ and
custom_properties_ so style rules containing only custom properties are
not discarded.

Add unit tests covering custom CSS properties in both inline styles and
stylesheet rules.

Bug: 573263143
Change-Id: Ib9cddf49d6687a34ab2c4195d2dc70eaf74e2aa3
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160850
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
This keeps platform-specific device text eligibility checks inside the
concrete device drivers rather than in CFX_RenderDevice, removes a
redundant ShouldDrawDeviceText() call from the Windows printer path,
and ensures non-rasterizing drivers will still receive DrawDeviceText()
calls on macOS.

Instead, since it is interrogating a font, make it an Apple-only
method of CFX_Font.

Bug: 573199238
Change-Id: I0a107edd4a47c7f22a3e9ffea7becd3e00f05493
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160830
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Add DestroyPlatformFont() to pair with CreatePlatformFont() on
CFX_GEModule::PlatformIface under IS_APPLE. This allows
CFX_Font::ReleasePlatformResource() to move from fx_apple_impl.cpp into
cfx_font.cpp alongside the rest of CFX_Font.

Change-Id: I01e730dcf380e36b80cf356b2e9dc530641e8bd5
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160652
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Replace fragile golden PNG image comparisons in FPDFEditEmbedderTest
text removal tests with display list text inspections. The display list
approach inspects the emitted text directly, avoiding rasterization,
hinting, and font engine discrepancies between FreeType and Fontations/
Skia.

Delete 22 obsolete golden PNG expectation files and remove the now
unused kHelloWorldRemovedPng constant.

Change-Id: I1f296f748e7ea025e3a5c63d51cbd2a7e9e85bf4
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160050
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Combine std::optional::has_value() and std::optional::value() checks on
CFX_Path::GetRect() into single EXPECT_EQ() calls, and inline the rest
of the `rect` checks into EXPECT_FALSE(path.GetRect(...).has_value()).

TAG=agy
CONV=6567e49a-585d-49fa-a2a2-cea8e1071f98

Change-Id: I774f0286072a80560b29ef2e17f7f90793b8029a
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160870
Reviewed-by: Andy Phan <andyphan@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Refactor GetNormalizedPoints() so the case where there are too many
points can return slightly earlier by checking a vector size before
appending to the vector. As such, the same vector can reserve one fewer
element.

Change-Id: I79f787c85e18bb0558042f340a8b7e48f788e086
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160890
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Andy Phan <andyphan@chromium.org>
This indicates a misbehaving embedder, so flag it with a CHECK()
while it is still active on the stack.

-- mass rename two hungarian length variables.
-- consistently name AutoRestorer local `restorer`

Bug: 572237007
Change-Id: Ice9212769e4072d76a427379aa13d02fa36be55d
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160615
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Provide a new value at construction time. Then use this to simplify
CPDFSDK_FormFillEnvironment.

Change-Id: Iadc1af0ae0e22f441380565219a814b7b56b080f
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160910
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Add third_party/.clang-format-ignore so clang-format does not format 3P
code.  It is copied from Chromium's file at the same relative location.

Change-Id: I4903da2517c409a10859d8a039642612f07cce9c
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160930
Reviewed-by: Andy Phan <andyphan@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Simplify the cases where assigning a bool, enum, or integer literal.

Change-Id: I3fc7104a819f232e668aa92704c145a5e9dc6fd9
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160911
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
This is possible now that the out-of-line constructor requirement has
been relaxed. Use designated initializers where possible.

-- convert members to google_style.
-- remove redundant assignment of members to default values.

Change-Id: If5144766a3c5c5b7809328d9263413364251af52
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160950
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Structs default to public access, so the explicit public: access
specifier is redundant and can be safely removed to clean up the
codebase.

-- Make aggregates where possible.
-- Make struct inheriting from class into a class.

Change-Id: I8f4762dbdbc380061db4d92cb1393c57483568ba
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160970
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
tsepez and others added 8 commits October 14, 2026 16:52
Replace fragile golden PNG image comparisons in
FPDFSaveWithFontSubsetEmbedderTest with display list codepoint checks.
The display list approach verifies the text emitted by the font
subsetting and save operations directly, avoiding rasterization,
hinting, and font engine discrepancies between FreeType and
Fontations/Skia.

Delete 12 obsolete golden PNG expectation files.

Change-Id: I63bab25d46cf02f6b9e40686ff63c5dea9b53448
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160070
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Replace fragile golden PNG image comparisons in FPDFEditEmbedderTest
for text addition, font loading, and glyph positioning tests with
display list inspections. Support UTF-8 multi-byte decoding in
ExtractTextLinesFromDisplayList to verify non-ASCII and CID font text
directly.

Delete 46 obsolete golden PNG expectation files.

Change-Id: Ib10a4210ee33aeccd315d1ca0f0b54187925efaa
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160350
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
- Remove CPDF_SyntaxParser::CreateForTesting() and inline the
  implementation into the only caller.
- Rename variable names in remaining ctors to use Google C++ style.
- Add inline comment to help document what "0" is.

Change-Id: I8f584ec4295bf8e0d9bb1cf1994423f6750a9f8a
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160991
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Move struct LayoutTestData out of the anonymous namespace inside
cpvt_section_unittest.cpp. The existing code causes GCC to fail with
-Werror=subobject-linkage.

Change-Id: If224f666c2a702d21a13d31d51e8c0e05a926d71
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160971
Reviewed-by: Andy Phan <andyphan@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Previously, form_callbacks kept per-page data alive
after a page was processed. Now, --render-repeats measures
image decode time in each repeat.

(When using --pages=1..10, form_fill_info_->loaded_pages keeps
per-page image caches alive for all pages still, so decoding many
pages needs memory for the images of all pages still. See an earlier
patch set on the CL for a different approach that changes that too.)

Follow-up to https://pdfium-review.googlesource.com/c/pdfium/+/132470

Bug: none
Change-Id: Ief69b738ce21f9e82c0f9a95a63f4ec201a9cfc8
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160790
Reviewed-by: Nico Weber <thakis@google.com>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Nico Weber <thakis@chromium.org>
ContinueStretchHorz() resamples one destination column at a time. Its
modal tap counts are 1 (no scaling in this axis) and 2 (bilinear
interpolation), so a bilinear row is a long run of columns doing the
same two multiply-accumulates on neighbouring source pixels, and that
pass is the largest single cost of rendering image-heavy pages.

Four consecutive columns sharing a tap count, whose source pixels lie
within 16 or 32 bytes of each other, are now resampled together: one
vectorized gather per tap pulls all four columns' source bytes into
32-bit lanes, one multiply-accumulate per tap does the arithmetic for
all four, and the result is packed and stored as one vector. The
arithmetic is the per-column path's, in tap order, on the same bytes
with the same weights, so the output is identical bit for bit.

PlanHorzGroups() runs once per stretch, after the weight table: it
finds maximal spans of same-tap-count columns, and for each whole group
of four within a span whose combined source window fits the gather it
precomputes the gather indices and weights (StretchHorzGroup). A span is
planned only if at least three in four of its groups fit; consecutive
fitting groups form a run (StretchHorzRun), which is the unit the
kernel handles per call. Columns not covered -- an odd tap count, a
short span, a group whose window does not fit -- take the per-column
path unchanged.

The kernels live in cstretchengine_hwy.cpp and use Highway. Three arms
are covered:

 - k8BppTo8Bpp and kManyBpptoManyBpp (BGR and BGRx destinations):
   StretchHorzRunSimd(), overloaded on the destination pixel type. 1bpp
   sources take the k8BppTo8Bpp arm too, on the row Expand1BppRow()
   produces, so the plan for them is made against that expanded row.
 - kManyBpptoManyBppWithAlpha: StretchHorzRunAlphaSimd(), where each
   tap's weight is weight * src.alpha / 255 -- a per-lane truncating
   divide that depends on the gathered alpha, so it is computed in the
   kernel with the exact reciprocal-multiply trick for division by 255
   (the (x + 1 + (x >> 8)) >> 8 approximation would be wrong here:
   weight * alpha reaches 65536 * 255, past where it is exact).

The kernels take the source row and destination as spans and process a
whole run per call, so the runtime target selection and the call happen
once per run (hundreds of groups for an unclipped bilinear row) rather
than once per four columns. Stores are packed vectors: 4 bytes for
8bpp, 16 bytes for BGRA and for BGRx (whose 4th bytes are read back
from the destination and kept, as the per-column path leaves them
untouched), and 8 + 4 bytes for BGR so that nothing is written past the
12 bytes a group owns.

The new unit tests compare every kernel, over a small fixed set of
groups and windows chosen to cover known edges (gather positions at
the start/middle/end of the window, weights at both ends and the
midpoint of the fixed-point range) for each (taps, window width)
variant, against a scalar re-derivation of what a group is documented
to compute, including the bytes a group must not touch, and check that
a run is processed in full.

Bug: 559426535
Change-Id: I4f5e3e977b4f6f9b184988ae518cf70abd868a20
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/158070
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Replace bitmap comparisons in FPDFFormFillEmbedderTest with
DisplayListRenderer assertions. This verifies rendered form text
and rectangle highlights directly against display list output instead of
platform-specific rasterized bitmaps, eliminating 42 obsolete golden
PNG files.

Change-Id: I47a8f536bf267559b3a4f4cf5506bb90fc2b1b07
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/160351
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
@bobsingor
bobsingor merged commit 145b6f8 into embedpdf/main Oct 17, 2026
1 check passed
@bobsingor
bobsingor deleted the embedpdf/sync/7c55203ed branch October 17, 2026 16:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants