printpdf 0.11.1

Rust library for reading and writing PDF files
Documentation
name: Build and test
on: [push, pull_request]

jobs:

  check-no-default-features:
    name: Check and test (no default features)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - run: cargo check --no-default-features --verbose
      # Not just `--lib`: the no-`text_layout` fallback font parser is only compiled in
      # this configuration, and it was returning a blank shell (no cmap, no widths) so that
      # external fonts rendered nothing at all (#258). `tests/no_text_layout.rs` covers it,
      # and only runs here.
      - run: cargo test --no-default-features --verbose

  check-feature-combinations:
    name: Check feature combinations
    runs-on: ubuntu-latest
    strategy:
      matrix:
        features:
          - "images"
          - "images,png"
          - "images,jpeg"
          - "images,gif"
          - "images,tiff"
          - "images,bmp"
          - "images,webp"
          - "images,png,jpeg,gif,tiff,bmp,webp"
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - run: cargo check --no-default-features --features "${{ matrix.features }}" --verbose

  check-and-test-unix:
    name: Cargo check and test on Unix systems
    strategy:
      matrix:
        channel: [stable]
        os: [ubuntu-latest, macos-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - name: Install ${{ matrix.channel }} toolchain
        uses: dtolnay/rust-toolchain@master
        with:
          toolchain: ${{ matrix.channel }}
      - run: cargo check --verbose --examples
      - run: cargo check --verbose
      # Re-enabled. This was commented out as "fails because of SIMD issues, test on
      # Windows only", which meant the whole suite only ever ran on Windows — and so a
      # panic in the HTML font-subsetting path (allsorts panics outright on an empty subset
      # cmap) sat here undetected, because it only reproduces with the fonts a Linux box
      # resolves.
      - run: cargo test --verbose


  check-and-test-windows:
    name: Cargo check and test on Windows
    strategy:
      matrix:
        target-sys: ["i686-pc-windows", "x86_64-pc-windows"]
        target-abi: ["msvc"]
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install toolchain for ${{ matrix.target-sys }}-${{ matrix.target-abi }}
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target-sys }}-${{ matrix.target-abi }}
      - run: cargo check --verbose --target ${{ matrix.target-sys }}-${{ matrix.target-abi }} --examples
      - run: cargo check --verbose --target ${{ matrix.target-sys }}-${{ matrix.target-abi }}
      - run: cargo test --verbose --target ${{ matrix.target-sys }}-${{ matrix.target-abi }}

  check-wasm32:
    name: Cargo check on wasm32
    strategy:
      matrix:
        channel: [stable]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install toolchain using wasm32-unknown-unknown target
        uses: dtolnay/rust-toolchain@master
        with:
          target: wasm32-unknown-unknown
          toolchain: ${{ matrix.channel }}
      - run: rustup target add wasm32-wasip1
      - run: rustup target add wasm32-wasip2
      - run: rustup target add wasm32-unknown-unknown
      - run: cargo check --verbose --target wasm32-unknown-unknown --examples
      - run: cargo check --verbose --target wasm32-unknown-unknown
      - run: cargo check --verbose --target wasm32-wasip1 --examples
      - run: cargo check --verbose --target wasm32-wasip1
      - run: cargo check --verbose --target wasm32-wasip2 --examples
      - run: cargo check --verbose --target wasm32-wasip2
      - run: cargo check --verbose --target wasm32-wasip2 --no-default-features
      # NOT --all-features: that pulls html_multithreaded + rayon
      # (rust-fontconfig/multithreading, image/rayon) which require rayon and can't
      # compile on wasm. Check the broad wasm-safe feature set instead.
      - run: cargo check --verbose --target wasm32-wasip2 --features "gif,jpeg,png,pnm,tiff,bmp,ico,tga,hdr,dds,webp"

  # Verifies the produced PDFs with poppler, which shares no code with printpdf.
  #
  # Every other test in this repo checks printpdf against printpdf. That symmetry is how
  # issue #277 shipped: the writer emitted an empty /FontFile2, the reader happily read a
  # font resource back out, and the round-trip test stayed green while Acrobat refused the
  # file. `pdffonts` and `pdftotext` are an independent oracle for the two things users
  # actually care about — does the font embed, and is the text copy-able.
  font-verification-external:
    name: Verify fonts with external tools (poppler)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - name: Install poppler-utils
        run: sudo apt-get update && sudo apt-get install -y poppler-utils
      - run: pdffonts -v && pdftotext -v
      - run: cargo test --features html --test external_tools --test font_embedding --test font -- --nocapture

  # THE RELEASE GATE.
  #
  # `cargo publish` STRIPS [patch.crates-io]. A crate published while that section exists
  # is built against dependencies nobody ever compiled or tested against — the local
  # checkout and the published artifact are different programs. That is exactly how 0.10.0
  # shipped broken: locally azul-layout came from a git branch whose
  # `ParsedFont::from_bytes` retains the source font bytes; on crates.io it resolved to
  # azul-layout 0.0.9, whose `from_bytes` does not, so every embedded font became an empty
  # /FontFile2 (#277). The same trap then bit azul itself twice while releasing 0.0.10.
  #
  # printpdf carries no [patch] any more. This job keeps it that way: it fails outright if
  # one reappears, then runs the font suite against the real registry dependency graph —
  # which is now, by construction, the one users get.
  publish-safety:
    name: No [patch], and the published dep graph passes the font suite
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - name: Install poppler-utils
        run: sudo apt-get update && sudo apt-get install -y poppler-utils
      - name: Refuse to build with a [patch.crates-io] section
        run: |
          if grep -q '^\[patch\.' Cargo.toml; then
            echo "::error::Cargo.toml has a [patch] section. cargo publish strips it, so the"
            echo "::error::published crate would be built against untested dependencies."
            echo "::error::Publish the patched dependency to crates.io and pin it instead."
            grep -n '^\[patch\.' -A5 Cargo.toml
            exit 1
          fi
          echo "no [patch] section — what we build is what we publish"
      - name: Dependency versions a published printpdf resolves to
        run: cargo tree --features html -i azul-layout || true
      - run: cargo test --features html --test external_tools --test font_embedding --test font --test no_text_layout || true
      - run: cargo test --features html --test external_tools --test font_embedding --test font
      - run: cargo test --no-default-features --test no_text_layout

  generate-pdf-artifacts:
    name: Generate PDF artifacts
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable

      # No-feature examples
      - name: Run no-feature examples
        run: |
          for ex in advanced bookmarks customfont graphics layers multipage text otf-font; do
            echo "=== Running $ex ==="
            cargo run --example "$ex" || true
          done

      # Image example
      - name: Run image example
        run: cargo run --example image --features "images,png" || true

      # SVG example
      - name: Run svg example
        run: cargo run --example svg --features svg || true

      # HTML-feature examples
      - name: Run HTML examples
        run: |
          for ex in html css_shapes html_full html_full_debug shape pagination_test \
                    baseline_alignment table_debug debug_pagination debug_displaylist \
                    pagination_boundary_test margin_collapse margin_collapse_inline \
                    margin_collapse_border_test margin_collapse_comprehensive; do
            echo "=== Running $ex ==="
            cargo run --example "$ex" || true
          done

      # Collect and upload PDFs
      - name: Collect PDFs
        run: |
          mkdir -p pdf-artifacts
          find . -maxdepth 1 -name '*.pdf' -exec cp {} pdf-artifacts/ \;
          ls -la pdf-artifacts/
      - name: Upload PDF artifacts
        uses: actions/upload-artifact@v4
        with:
          name: pdf-output-${{ github.sha }}
          path: pdf-artifacts/
          retention-days: 30