firecrawl / firecrawl/pdf-inspector
Positioned boxes shift left by the full text width for upright negative-font-size text
- Dominant language
- Rust
- Stars
- 19.1k
- Forks
- 1.3k
- Avg merge
- 9h 21m
- Merged PRs (30d)
- 51
Description
## Problem
In `pdf-inspector==1.18.0`, an upright `/Rotate 0` page whose text uses a negative `Tf` size returns positioned boxes off the left edge of the page.
The visible text starts at `x=72` on a 612-point-wide page. Both public positioned-text APIs instead return a same-width box ending at `x=72`: the first item is `x=-156.768`, `width=228.768`; the second is `x=-82.080`, `width=154.080`.
This makes a viewer highlight or region lookup miss text that is visibly on the page.
## Environment
- `pdf-inspector==1.18.0`
- CPython 3.13 on macOS arm64
- Public fixture: https://github.com/run-llama/liteparse/blob/python-v2.14.4/integration_tests_data/negative_font_size.pdf
- Fixture SHA-256: `2bdf661e6dec41b1802e79e8added8ca939821885881b9038810e1a5748b307d`
## Reproduction
Install `pdf-inspector==1.18.0`, save the linked public fixture as `negative_font_size.pdf`, then run:
```python
from pathlib import Path
import pdf_inspector as p
data = Path("negative_font_size.pdf").read_bytes()
items = p.extract_text_with_positions_bytes(data)
with_rotations = p.extract_text_with_positions_and_rotations_bytes(data)
for item in items:
print(item.text, item.x, item.y, item.width, item.height, item.rotation, item.font_size)
print("page_rotations:", with_rotations.page_rotations)
print("same items:", [(x.text, x.x, x.width) for x in items] == [
(x.text, x.x, x.width) for x in with_rotations.items
])
```
Actual output on 1.18.0:
```text
Upright text drawn with a negative font size -156.76800537109375 720.0 228.76800537109375 12.0 0.0 12.0
Second line stays upright too -82.08000183105469 692.0 154.0800018310547 12.0 0.0 12.0
page_rotations: []
same items: True
```
## Expected
The fixture visibly renders both lines upright beginning at `x=72`. Poppler's independent `pdftotext -bbox` output reports `xMin=72.000000` for each line, with the first ending at `xMax=300.768000` and the second at `xMax=226.080000`.
The positioned API should return the axis-aligned visible glyph bounds, so the expected starts are `x=72` with the same widths. The page has `MediaBox [0 0 612 792]` and `/Rotate 0`; no CropBox or page-turn transform is involved.
## Scope
This is a focused geometry defect, not a claim that the 1.18.0 coordinate-frame changes are broadly incorrect. The public CropBox fixture introduced in 1.18.0 behaves as documented in a separate local check.
PR #486 added rotated-run geometry and handling for negative `Tf` text. It is a relevant change to inspect, but this report does not assume the exact root cause or prescribe a fix.
The fixture is public and fictional. It contains only these two visible sentences and no personal metadata, attachments, JavaScript, forms, encryption, customer content, or internal paths.
Contributor guide
No contributing guide indexed for this repository
Research direction
Reproduce the issue through extract_text_with_positions_bytes and extract_text_with_positions_and_rotations_bytes using the linked negative_font_size.pdf fixture. Inspect PR #486 and the positioned-text geometry entry points, then verify that both APIs return visible bounds starting at x=72 with the expected widths and that the existing rotation behavior remains consistent.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, rust
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 74/100