Skip to content

feat(api): add text-to-outlines endpoint (Ghostscript -dNoOutputFonts) - #8201

Closed
nonofr91 wants to merge 2 commits into
Stirling-Tools:mainfrom
nonofr91:feat/text-to-outlines
Closed

nonofr91 wants to merge 2 commits into
Stirling-Tools:mainfrom
nonofr91:feat/text-to-outlines

Conversation

@nonofr91

@nonofr91 nonofr91 commented Sep 25, 2026 •

Copy link
Copy Markdown

Description of Changes

Adds POST /api/v1/misc/text-to-outlines, which converts all text in a PDF to vector outlines via Ghostscript -dNoOutputFonts.

Converting text to outlines is a standard prepress step — it removes font dependencies and font-licensing concerns when sending files to print. This was requested in #471.

Details:

  • API-only endpoint (multipart form, accepts fileInput), consistent with the "PDF API" scope for prepress features discussed in Setting page info while resizing or cropping page #1194/[Feature Request]: Using Page boxes for scaling and potentially other tools such as bleed etc #2004.
  • Registered in the Other and Ghostscript endpoint groups, so it is automatically disabled when Ghostscript is not installed; the controller additionally returns ToolRequiredException (createGhostscriptRequiredException) when the group is off.
  • Uses the existing ProcessExecutor + TempFileManager pattern (same as crop-with-Ghostscript); output analysed via detectGhostscriptCriticalError before the return code is checked.
  • Non-zero Ghostscript exit codes surface as GhostscriptException; interruption is wrapped via createProcessingInterruptedException.

Refs #471


Checklist

General

Documentation

Translations (if applicable)

UI Changes (if applicable)

  • Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR)

Testing (if applicable)

  • I have run task check to verify linters, typechecks, and tests pass
  • I have tested my changes locally. Refer to the Testing Guide for more details.

Summary by CodeRabbit

  • New Features
    • Added a PDF tool that converts text into vector outlines and returns the result as a PDF. Requires Ghostscript to be enabled.

Converts all text in a PDF to vector outlines via Ghostscript
-dNoOutputFonts — a standard prepress step that removes font
dependency and licensing issues before print.

Registered in the Other and Ghostscript endpoint groups so it is
disabled automatically when Ghostscript is not installed, and the
controller returns a ToolRequiredException when the group is off.

Refs Stirling-Tools#471
@nonofr91
nonofr91 requested review from a team, Ludy87 and balazs-szucs as code owners September 25, 2026 18:57
@github-actions github-actions Bot added enhancement New feature or request Java Pull requests that update Java code Back End Issues related to back-end development API API-related issues or pull requests Test Testing-related issues or pull requests labels Sep 25, 2026
@coderabbitai

coderabbitai Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: f949ea43-5580-404f-93fd-aaecf8bacf86

📥 Commits

Reviewing files that changed from the base of the PR and between 438bad3 and 90d3469.

📒 Files selected for processing (4)
  • engine/src/stirling/models/tool_io.py
  • engine/src/stirling/models/tool_models.py
  • frontend/editor/src/core/types/toolApiTypes.ts
  • frontend/editor/src/core/types/toolIO.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 6 remain after this review.


📝 Walkthrough

Walkthrough

Adds a multipart PDF endpoint that uses Ghostscript to convert text to outlines and returns the resulting PDF. Registers the endpoint in Java, Python, and frontend tool metadata. Adds controller tests and a Cucumber scenario.

Changes

Text-to-outlines conversion

Layer / File(s) Summary
Endpoint and tool contracts
engine/src/stirling/models/tool_models.py, engine/src/stirling/models/tool_io.py, frontend/editor/src/core/types/toolApiTypes.ts, frontend/editor/src/core/types/toolIO.ts
Registers the endpoint in the Python tool models and frontend API types. The tool metadata declares PDF input, PDF output, and single-input, single-output arity.
Endpoint behavior and registration
app/core/src/main/java/stirling/software/SPDF/controller/api/misc/TextToOutlinesController.java, app/common/src/main/java/stirling/software/SPDF/config/EndpointConfiguration.java
The endpoint validates the input PDF and Ghostscript availability, runs Ghostscript with -dNoOutputFonts, and returns the output PDF. It handles Ghostscript errors and interrupted processing. The endpoint is registered in the Other and Ghostscript groups.
Endpoint validation
app/core/src/test/java/stirling/software/SPDF/controller/api/misc/TextToOutlinesControllerTest.java, testing/cucumber/features/external.feature, testing/endpoints.txt
Tests cover disabled Ghostscript, successful conversion, and a nonzero Ghostscript result. A Cucumber scenario checks for a nonempty PDF response, and the endpoint inventory includes the new route.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant TextToOutlinesController
  participant Ghostscript
  Client->>TextToOutlinesController: Submit multipart PDF
  TextToOutlinesController->>Ghostscript: Run with -dNoOutputFonts
  Ghostscript-->>TextToOutlinesController: Return conversion result
  TextToOutlinesController-->>Client: Return outlined PDF
Loading

Suggested reviewers: frooodle

Merge Risk: 🔵 Low · up to 90d34

PDFs using bitmap fonts may retain bitmap text despite the vector-outlines promise, which could mislead prepress users expecting vector-only output. The risk is limited to those inputs but should be clarified.

Security Architecture Review

Security architecture risk: 🟡 Moderate · up to 90d34

A new upload route invokes Ghostscript on submitted PDFs. Existing availability and execution controls reduce exposure, but the access rules and process isolation of deployed instances are not established. The endpoint can also report success without confirming that conversion produced a usable PDF.

Retained concerns

  • Medium · security · inferred: The new public route gives callers who can reach the API another way to submit PDFs to a Ghostscript process. The effective caller policy, input ceilings, and process privileges are not established, so containment of this added attack path cannot be assessed fully.
  • Low · reliability · inferred: A zero exit code can yield an HTTP 200 PDF response without verification that Ghostscript produced a nonempty PDF. This weakens containment of an unsuccessful conversion, although the demonstrated case uses a mocked process rather than production Ghostscript.
Security review details

Security Blast Radius

  • inferred — A caller able to access the new route can submit PDFs for processing by Ghostscript in an app instance. The instance's effective user privileges, tenant exposure, and deployment-level isolation are not established.

Security Findings and Attack Paths

  • inferred — The relevant path is uploaded PDF bytes to a temporary input file to the Ghostscript parser. This establishes exposure to a native processor, not a verified exploit or proof that authentication can be bypassed.

Trust Boundaries and Controls

  • observed — The handler enforces the Ghostscript-group gate and nonempty input; the shared executor limits concurrent processes and their run time. These controls do not establish the caller policy or OS-level isolation of Ghostscript.

Resilience and Maintainability Implications

  • observed — Interruption restores the thread interrupt flag, and the process executor forcibly terminates the process and descendants on interruption or timeout. Per-request temporary-file ownership covers ordinary failure paths.

Hardening Proposals

  • proposed — Confirm the deployed route's authorization, upload ceilings, and Ghostscript process privileges; reject a missing or empty conversion artifact before returning a successful PDF response.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 8 functions across 7 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the addition of the text-to-outlines API endpoint and the Ghostscript option used.
Description check ✅ Passed The description explains what changed, why it was added, implementation details, references, and testing. The documentation checklist item remains unchecked, but this is non-critical for the API-only …
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

Comment @coderabbitai help to get the list of available commands.

@balazs-szucs

balazs-szucs commented Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator

Hi,

We are generally trying to move away from GS, and also this isn't really hooked up to anything, so I fail to see how this is useful.

In general:

  • No GS implementation is preferable.
  • Some way to integrate this into existing features or endpoints would be good.
  • Or into its own feature though for that this is seem to be very lean in term potential utility

Thanks.

coderabbitai[bot]

This comment was marked as resolved.

Keeps the committed generated models (frontend toolApiTypes/toolIO,
engine tool_models/tool_io) in sync with the Java OpenAPI spec.

Generated with: task tool-models
@nonofr91
nonofr91 requested a review from a team as a code owner September 25, 2026 19:42
@github-actions github-actions Bot added Front End Issues or pull requests related to front-end development engine Issues or pull requests related to the engine labels Sep 25, 2026
@nonofr91

Copy link
Copy Markdown
Author

Thanks for the review — fair points. A Ghostscript-dependent standalone endpoint doesn't fit the project's direction. Closing this; I'll keep iterating on my fork and may come back with an integrated, non-GS approach.

@nonofr91 nonofr91 closed this Sep 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

API API-related issues or pull requests Back End Issues related to back-end development engine Issues or pull requests related to the engine enhancement New feature or request Front End Issues or pull requests related to front-end development Java Pull requests that update Java code Test Testing-related issues or pull requests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants