fix(bbb-web): Fallback to Rasterization if SVG has (lots of) Mask Tags - #25
Closed
antobinary wants to merge 3 commits into
Closed
antobinary wants to merge 3 commits into
antobinary wants to merge 3 commits into
Conversation
…d by default Refines the previous commit: masks are common in ordinary PDFs (soft-masked/alpha images - the bundled default.pdf title page yields 3), so rasterizing on the mere presence of a <mask> tag would rasterize most real-world decks. Replace the any-mask check with a configurable maskTagThreshold wired like the existing imageTagThreshold, useTagThreshold and placementsThreshold. The default is 0 (disabled), following the bigbluebutton.properties convention where 0 turns a limit off: pdftocairo 24.02.0 shipped with Ubuntu 24.04 - BBB 4.0's target OS - generates correct mask values, so no rasterization is needed on a stock install and vector slides are preserved. Setting maskTagThreshold=1 rasterizes any slide whose generated SVG contains a mask (the previous commit's behavior); setting it to N rasterizes slides with N or more masks. The mask count is always collected and reported in the potential_problem_with_svg analytics log entry for tuning. Adds a ScalaTest spec for the SvgConversionHandler tag counting, backed by a minimal soft-masked sample PDF and the SVG that pdftocairo 24.02.0 actually produced from it (2 <mask>, 3 <image>, 2 <path>, 4 <use>). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ation fallback Uploads the same soft-masked sample PDF used by the bbb-common-web unit spec and asserts the served slide SVG is the rasterized embedded-PNG form produced by SvgImageCreatorImp.createSvgWithEmbeddedPng() - a single <image href="data:image/png;base64,..."> and no vector <path> elements. BBB 4.0 renders slides as tldraw image assets, so a visual snapshot cannot tell a rasterized slide apart from a vector slide of the same content; inspecting the served SVG file isolates the feature instead. maskTagThreshold is a server-side bbb-web setting with no client-settings hook, so nothing applies it automatically: the test requires bbb-web to be restarted with maskTagThreshold=1 in /etc/bigbluebutton/ bbb-web.properties and is tagged @setting-required:maskTagThreshold, which keeps it out of the default CI gate. The mechanics (upload flow, conversion wait, served-SVG fetch via the tl-image asset URL incl. pageToken/sessionToken query params, and the embedded-PNG discriminator in both directions) were validated against a live 4.0 server: a default-config upload serves pdftocairo vector SVG (no match), and a forceRasterizeSlides=true upload serves the embedded-PNG form (match). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
⏳ Automated tests are running... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Refined follow-up to bigbluebutton#24393 by @paultrudel, targeting 4.0. Structured as three commits so the refinement is reviewable:
<mask>tags during SVG analysis and rasterize any slide whose generated SVG contains one.maskTagThreshold(wired likeimageTagThreshold/useTagThreshold/placementsThreshold), disabled by default (0), plus a ScalaTest spec with a committed soft-masked sample.@setting-requiredPlaywright test asserting a masked slide is served as rasterized SVG when the feature is enabled.Background
Certain scanned PDFs contain images whose soft masks pdftocairo 22.02.0 (Ubuntu 22.04 / BBB 3.0) converted into SVG
<mask>elements with wrong values, leaving slides partially blank or dark in the browser — the problem bigbluebutton#24393 addressed by rasterizing on any mask.Addressing @gustavotrott's review of bigbluebutton#24393
The objection was that most PDFs contain
<mask>tags, so presence of a mask isn't the problem — pdftocairo was writing masks with wrong values. Empirically confirmed: BBB's owndefault.pdftitle page yields 3<mask>tags under pdftocairo 24.02.0, so "any mask → rasterize" would rasterize BBB's own default deck (see table). This PR never rasterizes on mere mask presence.Configuration (follows the bigbluebutton.properties
0-disables convention)maskTagThreshold(default0, disabled):0— disabled. pdftocairo 24.02.0 (Ubuntu 24.04, BBB 4.0's target OS) generates correct mask values, so no rasterization is needed on a stock install and vector slides are preserved. Default behavior is bit-identical to current 4.0.1— rasterize any slide whose generated SVG contains a<mask>(this reproduces the fix(bbb-web): Fallback to Rasterization if SVG has Mask Tags bigbluebutton/bigbluebutton#24393 behavior).N— rasterize only slides with N or more masks.The mask count is always collected and reported in the
potential_problem_with_svganalytics entry for tuning, even when disabled.Poppler on BBB 4.0
BBB 4.0 targets Ubuntu 24.04 → poppler-utils 24.02.0, the version @gustavotrott identified as fixing the wrong-mask-values bug (verified: 24.02.0 on a 4.0 Noble install vs 22.02.0 on 3.0 Jammy). That's why the default is disabled.
Evidence (bbb 4.0 install, pdftocairo 24.02.0, exact production analysis command)
0)maskTagThreshold=1Counts are real pdftocairo output; decisions were computed by feeding that stdout into the compiled
SvgConversionHandlerand evaluating each variant's condition — a decision-logic evaluation, not a full upload run.Testing
SvgConversionHandlerTestreplicates thegrep -oE '<image|<path|<use|<mask' | sort | uniq -canalysis pipeline against a committed sample — a minimal PDF with an /SMask image and the SVG pdftocairo 24.02.0 produced from it — asserting the parsed counts (mask=2, image=3, path=2, use=4) plus zero-mask and malformed-stdout cases. All 3 pass (ScalaTest 3.0.8, JDK 21). Note: bbb-common-web specs aren't currently run in CI, so this documents the parsing/threshold contract rather than acting as a gate today.@setting-required:maskTagThreshold): uploads the same soft-masked sample and asserts the served slide SVG is the rasterized embedded-PNG form produced bycreateSvgWithEmbeddedPng()(<image href="data:image/png;base64,...and no<path>), fetched via the tl-image asset URL. 4.0 renders slides as tldraw image assets, so a visual snapshot can't distinguish rasterized from vector — inspecting the served SVG isolates the feature.maskTagThresholdis a server-side setting with no client-settings hook, so the test requires bbb-web restarted withmaskTagThreshold=1and is excluded from the default CI gate. Mechanics validated both ways on a live 4.0 server: default config serves vector SVG (assertion rejects); aforceRasterizeSlides=trueupload serves the embedded-PNG form (assertion matches).