Skip to content

stet 0.8.3

Latest

Choose a tag to compare

@github-actions github-actions released this 01 Oct 13:28

Added

  • Transparent page backgrounds: --transparent for --device png,
    and PageBackground in the library.
    Pages normally render onto white
    paper; with the option, every pixel no mark covers is left at alpha 0 and
    the output is straight-alpha RGBA, so artwork (EPS, AI, PDF) can be
    placed over other content with its unpainted areas clear. PostScript and
    PDF input both honour it, on every page. In the library,
    InterpreterBuilder::page_background(PageBackground::Transparent) makes
    Interpreter::render return clear pages, and stet-render adds
    render_to_rgba_with_background and SkiaDevice::set_page_background,
    and stet-pdf-reader adds PdfDocument::render_page_to_rgba_with_background
    (with PageBackground re-exported); render_to_rgba,
    render_to_rgba_with_layers and render_page_to_rgba keep their
    signatures and white paper. Contributed by @jungseohaan (#4).
  • stet-fonts writes CFF and converts Type 1 charstrings to Type 2.
    cff_writer serialises a CID-keyed CFF font (and read_cid_font /
    CidFont::subset read and subset one); type1_to_type2 converts a
    Type 1 charstring to Type 2, keeping stem hints, hint replacement (as
    hintmask) and flex; cid_type0 reads the glyph data of a CIDFontType 0
    font with Type 1 charstrings. They are what PDF output of those fonts is
    built on.
  • setoverprintmode and currentoverprintmode, the PostScript
    spelling of PDF's /OPM. They are Adobe extensions outside the PLRM,
    which Ghostscript also provides. With true setoverprintmode and
    overprint on, a DeviceCMYK paint leaves the plates whose component is 0
    untouched, so 0 1 0 0 setcmykcolor over cyan gives blue rather than
    magenta, and 0 0 0 0 setcmykcolor paints nothing, as in Ghostscript.
    pdftops output tests for the operator before calling it, so until now
    every /OPM 1 in a PDF converted to PostScript was silently treated as
    mode 0. Converting PostScript to PDF now carries the mode into /OPM.
    As with setoverprint, images do not overprint yet.

Changed

  • stet_core::graphics_state::GraphicsState has a new field,
    overprint_mode,
    which setoverprintmode sets (see Added). Code that
    builds a GraphicsState with a struct literal no longer compiles; use
    GraphicsState::new() and set the fields you need. Reading the struct is
    unaffected. It is the interpreter's graphics state, public only because
    its module is, and will be marked #[non_exhaustive] in a later release
    like PdfGraphicsState.
  • The embedded URW++ base 35 fonts are distributed under the SIL Open
    Font License 1.1
    instead of the GNU AGPL v3 with a font exception. In
    2017 URW++ licensed the Version 2.0 fonts under a choice of AGPL, LPPL
    1.3c or OFL 1.1; stet takes the OFL option. The fonts are unchanged. A
    program that links stet, stet-pdf-reader or stet-wasm no longer
    carries AGPL-licensed data: the OFL allows bundling the fonts with any
    software, commercial included, as long as they are not sold on their own
    and their licence goes with them. LICENSE-URW-FONTS in each of those
    crates, and THIRD-PARTY-NOTICES.txt in the release archives, carry the
    OFL text and the basis for it.

Fixed

  • A bare stet now opens the viewer when a page is shown. With no
    input file, stet starts the PostScript REPL as before, and the first
    showpage opens the viewer on the page drawn. --help and both READMEs
    described this behaviour, but a bare stet selected the png device,
    so showpage in the REPL wrote nothing and opened no window. A session
    that never shows a page still opens no window. Builds without the
    viewer are unchanged.

  • -o without --device now writes a PNG in viewer builds. The
    --help examples stet -o out.png --pages 1 doc.pdf and
    stet -o 'p-%03d.png' doc.pdf failed with "--output does not apply to
    --device viewer", naming a device the command never asked for. -o
    now selects png unless a device is given, as headless builds
    already did.

  • The REPL banner shows the real version. It printed
    stet Version 0.1.0 (2026-02-25) whatever the release, and
    revisionstring and revisiondate in systemdict held the same stale
    values, and the integer revision was always 1. They now carry the
    release version and date; revision is the version with two digits
    each for minor and patch, so 0.8.2 is 802.

  • setoverprint now works for spot colours in PostScript. A
    Separation or DeviceN colour painted with overprint on knocked out the
    process colours beneath it, where PDF input with the same content
    overprinted correctly. Now only the colorants the colour space names are
    painted: a spot over cyan keeps the cyan, and /Separation /Magenta or
    a DeviceN of [/Yellow …] leaves the other process plates alone. This
    covers fills, strokes and text; images and imagemask do not overprint
    yet. DeviceCMYK still paints all four plates unless setoverprintmode
    selects mode 1 (see Added). Two related bugs went with it: a cached Type 3 glyph kept
    the overprint setting from when it was first drawn, and PostScript
    overprint turned off entirely on pages small enough to render in one
    piece, so the same file could overprint at 300 dpi and not at 72.

  • Text in CIDFontType 0 fonts built with StartData is drawn. These
    CID fonts carry Type 1 charstrings reached through a CID map, and pdftops
    writes every CFF-based CID font this way, Chinese, Japanese and Korean
    text and subset OpenType fonts included. stet read the glyph data only to
    skip it, so show raised invalidfont and the text vanished: 161 files
    in the test corpus lost some or all of theirs. show, stringwidth,
    charpath and xshow/yshow/xyshow now draw them, in both writing
    modes, with each FDArray font's own FontMatrix, lenIV and
    subroutines. A CID the font has no glyph for shows CID 0, as the CIDFont
    specification requires, instead of an empty advance.

    Converting such PostScript to PDF embeds the fonts, subset to the CIDs
    used, as CFF (/CIDFontType0C, the only CIDFont program PDF has for
    them): each Type 1 charstring is converted to Type 2 with its hints,
    hint replacement and flex kept. CFF CID fonts loaded through
    FontSetInit are embedded the same way. Both used to fall back to an
    unembedded simple font, which garbled the text.

  • TrueType CID fonts find their glyphs through CIDMap. A Type 2
    CIDFont maps each CID to a TrueType glyph through its CIDMap table
    (PLRM Table 5.17), which pdftops writes for every CID-keyed TrueType
    font it converts. stet used the CID itself as the glyph index, correct
    only when the map is the identity, so text in subset fonts came out as
    gibberish (22 files in the test corpus). PDF output did worse: it looked
    CIDs up in the font's TrueType cmap table, which these fonts do not
    have, so every glyph became .notdef. Both now read CIDMap in its
    string and array forms, and in the integer and dictionary forms
    Ghostscript also accepts; a CID the map does not define shows CID 0's
    glyph.

  • Vertical CID text follows the PLRM, and PDF output keeps it
    vertical.
    A glyph gets its vertical (writing mode 1) metrics from the
    CIDFont's Metrics2 or CDevProc (PLRM 5.9.2), which stet now
    supports; CDevProc may change widths in horizontal text too. A font
    with neither has one set of metrics, and the PLRM ignores the writing
    mode for it: its text runs horizontally, as in Ghostscript. stet instead
    gave every CIDFont default vertical metrics, and read DW2, which is a
    PDF key, not a PostScript one; pdftops' conversions of vertical text,
    whose fonts carry no vertical metrics, now render as Ghostscript renders
    them. PDF output wrote every CID font with a horizontal CMap, so
    vertical text ran across the page; it now uses Identity-V with /W2
    holding the metrics the interpreter used, and a CIDFont shown in both
    directions becomes one PDF font per direction.

  • Loading a CFF FontSet leaves the dictionary stack as it was, and
    defines the FontSet.
    A FontSet file begins the FontSetInit ProcSet
    and has no end after its binary data (Adobe TN 5176, Appendix E), so
    StartData must end it, as Ghostscript's does; stet's left the ProcSet
    on the dictionary stack for the rest of the job. StartData also
    discarded the FontSet's name: it now defines the fonts as that FontSet
    resource, and /NimbusRoman-Regular-CFF /FontSet findresource finds
    stet's own FontSet, whose file named it differently.

  • Text in PDF output keeps its spacing. Strings on one line are
    joined into a TJ run spaced by the glyph widths, which were looked up
    byte by byte instead of by 2-byte CID: when the page also used the CIDs
    matching those bytes (CID 0x0105 read as CIDs 1 and 5), the next
    string landed in the wrong place. ashow and widthshow spacing on CID
    text was dropped altogether. And in any font, each kern in a run was
    rounded to a thousandth of an em, so a line of separately placed glyphs,
    as pdftops writes, drifted by a fraction of a point by its end. All
    three now match the interpreter.

  • definefont no longer replaces the font a copy was made from. It
    filed each font in FontDirectory under its /FontName rather than
    under the key it was defined with, which the PLRM requires. A re-encoded
    copy keeps its original's FontName, so defining one — pdftops does it
    for every font a page uses, /F1_0 from /Helvetica — silently
    replaced the original, and a later /Helvetica findfont returned the
    copy with its encoding.

  • PDF output keeps each encoding of a font. Two instances of one font
    with different encodings — pdftops writes ZapfDingbats re-encoded beside
    the standard one — shared one PDF font resource, whose encoding was
    merged code by code, first come first served, so the second instance
    drew the first one's glyphs. Each such instance now gets its own
    resource; instances whose encodings agree, like dvips's re-encoded
    copies, still share one, and the font program keeps every instance's
    glyphs.

  • Subset CFF CID fonts draw the right glyphs. A CID-keyed CFF font
    loaded through FontSetInit had its glyphs looked up as if each CID
    were the glyph's index in the font, which holds only for a complete
    font; in a subset one, as producers embed them, text drew the wrong
    glyphs or none.

  • Type 1 glyphs that draw without an explicit rmoveto no longer
    sprout lines from the page corner.
    The Type 1 format lets a glyph
    start drawing at the point hsbw sets, and closepath, unlike
    PostScript's, leaves the current point in place, so a following line
    needs no rmoveto either. stet began such a path with a line and no
    move, which the renderer drew from the device origin. This affects Type
    1 fonts in PostScript and in PDF alike; pdftops' conversions of CFF
    fonts rely on it.

  • Separation and DeviceN colorant names given as strings are now
    recognised.
    The PLRM lets a colorant be a name or a string, and
    pdftops writes every one as a string ((Black), (PANTONE 273 C),
    (All)), but stet read any string as an empty name. Under overprint,
    process colorants were then taken for spots, so (Black) or (Magenta)
    knocked out the other plates, and a DeviceN backdrop of (Black) plus a
    spot lost its black. The GWG 3.0 gray-overprint test page converted with
    pdftops now matches Ghostscript. PDF output carries the real spot names
    rather than empty ones. A colorant that is neither a name nor a string is
    now a typecheck, as in Ghostscript, instead of being accepted silently.

  • initgraphics and showpage no longer reset the whole graphics
    state.
    The PLRM has initgraphics reset the transformation matrix,
    path, clip, colour and line settings only, and leave everything else
    alone: stroke adjustment, the font, and all the device-dependent
    parameters (overprint, flatness, smoothness, transfer, halftone, black
    generation and undercolor removal). stet reset all of them, and since
    showpage performs an initgraphics, a program that set overprint or a
    transfer function once lost it from the second page on. Ghostscript
    keeps them. Two smaller fixes go with it: setpagedevice now keeps the
    current font, as the PLRM requires, and a clip set after initgraphics
    inside a gsave is now undone by grestore, which could previously
    leave the inner clip in force.

  • stet-cli's crates.io page no longer shows a failing docs.rs badge.
    docs.rs documents libraries only, and stet-cli is a binary, so its
    build has failed for every release. The badge is gone and the
    crate's Documentation link now leads to the command-line usage.

Downloads

stet-<version>-x86_64-unknown-linux-musl.tar.gz is the one most people
want: statically linked, no glibc requirement, no runtime libraries, no GUI.
It is the right choice for servers, CI and containers.

The -gnu Linux build adds the desktop viewer and needs glibc 2.35 or newer
(Debian 12, Ubuntu 22.04 and later) plus X11 or Wayland and OpenGL to open a
window. Rendering to files works without them.

macOS: the binaries are unsigned, so opening a downloaded archive from
Finder trips Gatekeeper ("cannot be opened because the developer cannot be
verified"). Installing with curl avoids it entirely, because the quarantine
attribute is set by the downloading application and curl does not set one:

curl -L <asset-url> | tar xz

If you already downloaded it in a browser, clear the flag with
xattr -dr com.apple.quarantine stet.

Windows: SmartScreen will warn that the publisher is unknown; choose
More info -> Run anyway. Code signing certificates cost money and stet does
not have one.

Rendering is identical across these artifacts with one caveat: the musl
build's libm differs from glibc's in the last bits, which can shift
antialiasing coverage by a pixel or two on heavily curved PostScript
artwork (measured: 265 of 5.4M pixels on one sample, invisible in practice;
all PDF samples tested were byte-identical). Do not generate rendering
baselines with one build and compare them against another.

Verify a download against SHA256SUMS.