codex-pdf 1.7.1__tar.gz → 1.7.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/CLAUDE.md +1 -1
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/PKG-INFO +1 -1
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/clients/ts/package.json +1 -1
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/README.md +1 -1
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/wrangler.toml +1 -1
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/pyproject.toml +1 -1
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/geom/path.py +5 -4
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/version.py +1 -1
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_geom.py +20 -11
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/uv.lock +1 -1
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/.cursor/rules/service-ownership.mdc +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/.github/workflows/ci.yml +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/.gitignore +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/.windsurf/rules/service-ownership.md +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/CONTRIBUTING.md +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/Dockerfile +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/LICENSE +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/Procfile +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/README.md +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/SECURITY.md +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/clients/ts/README.md +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/clients/ts/package-lock.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/clients/ts/src/color.ts +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/clients/ts/src/index.test.ts +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/clients/ts/src/index.ts +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/clients/ts/tsconfig.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/.github/workflows/deploy.yml +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/package-lock.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/package.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/src/cache_key.ts +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/src/env.ts +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/src/handlers/extract.ts +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/src/handlers/probe.ts +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/src/index.ts +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/src/sse_tee.ts +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/test/cache_key.test.ts +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/codex-edge/tsconfig.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/docs/architecture.md +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/docs/cli.md +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/docs/contract.md +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/docs/deploy.md +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/docs/operations/codex-change-ripple.md +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/docs/operations/marketing-deploy-template.md +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/docs/parity.md +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/docs/preflight-ingest.md +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/docs/service-ownership-contract.md +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/railway.speculator.toml +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/railway.toml +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/audit/mislocated-closure.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/audit/produce_surface.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/dieline_calibration_report.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/parity/codex_deep.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/parity/codex_inventory.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/parity/codex_summary.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/parity/criterion4_parser_surface.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/parity/pdfx4_deep.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/parity/pdfx4_inventory.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/parity/pdfx4_summary.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/parity/render_baseline.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/reports/parity/viewer_essentials.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/CHANGELOG.md +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-annotation.schema.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-box.schema.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-color-space.schema.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-document.schema.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-font.schema.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-form-xobject.schema.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-image.schema.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-issue.schema.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-ocg.schema.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-output-intent.schema.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-page-object.schema.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-page.schema.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-preflight-report.schema.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-source.schema.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-spot-colorant.schema.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-transparency-tree.schema.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-trap-evidence.schema.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/codex-warning.schema.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/schemas/v1/probe.schema.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/scripts/calibrate_dieline_heuristics.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/scripts/parity_viewer_essentials.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/scripts/produce_surface_audit.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/__init__.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/api/__init__.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/api/auth.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/api/blob_store.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/api/cache.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/api/main.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/api/url_ingest.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/api/warmup.pdf +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/api/warmup.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/cli.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/client/__init__.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/client/http_client.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/color/__init__.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/color/alt_space.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/color/color_math.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/color/curated.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/color/data/pantone_reference.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/color/normalize.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/color/pantone.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/color/resolver.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/eval/__init__.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/eval/ps_type4.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/__init__.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/annotations.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/color.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/common.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/content_inventory.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/dieline_detector.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/document.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/fonts.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/forms.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/images.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/ocg.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/probe.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/signals.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/structure.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/summary.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/transparency.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/extract/trapping.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/geom/__init__.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/geom/box.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/geom/matrix.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/geom/tile.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/geom/units.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/models/__init__.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/models/v1.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/parity.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/preflight_ingest/__init__.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/preflight_ingest/adapters.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/render/__init__.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/render/_common.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/render/content_stream.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/render/layer.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/render/page.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/render/separations.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/schema.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/speculator/__init__.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/speculator/__main__.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/src/codex_pdf/speculator/consumer.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/conftest.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/fixtures/conforming/minimal.pdf +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/fixtures/generate_fixtures.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/fixtures/violating/no_output_intent.pdf +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/fixtures/violating/no_trim_box.pdf +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/fixtures/violating/no_xmp.pdf +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/fixtures/violating/pdf_1_4.pdf +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/golden/1.0.0/reference.json +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_alt_space.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_api.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_cache.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_cli_contract.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_client_routing.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_color.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_extract_analysis_signals.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_extract_structural.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_golden.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_golden_corpus.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_models.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_parity.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_pdf_sha256.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_preflight_ingest.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_produce_surface_audit.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_schema.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_schemas_all.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_speculator.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_summary_dieline.py +0 -0
- {codex_pdf-1.7.1 → codex_pdf-1.7.2}/tests/test_summary_spot_colors.py +0 -0
|
@@ -25,7 +25,7 @@ For new products (Forge, Trap, Impose, Marks, etc.), map capabilities to one own
|
|
|
25
25
|
|
|
26
26
|
When work spans layers, define a contract seam and keep logic in its owner service.
|
|
27
27
|
|
|
28
|
-
## Deployed surface (1.7.
|
|
28
|
+
## Deployed surface (1.7.2)
|
|
29
29
|
|
|
30
30
|
Codex now runs as **three services** in production. They share the
|
|
31
31
|
same content-addressed cache key format
|
|
@@ -10,7 +10,7 @@ the Railway codex-pdf service.
|
|
|
10
10
|
- **Account**: `99aa3f9229469650a746a7d39ac58448` (`Quincy@thinkneverland.com's Account`)
|
|
11
11
|
- **KV namespace `CACHE`**: `89a21ce1937046018a3d9d38f4e763ff` (preview `a4856d6f3b244087b907c189c2a2277d`)
|
|
12
12
|
- **Origin** (`CODEX_ORIGIN_URL`): `https://codex-pdf-lint-sidecar-production.up.railway.app`
|
|
13
|
-
- **Codex version pinned**: `1.7.
|
|
13
|
+
- **Codex version pinned**: `1.7.2` (`CODEX_VERSION` var — bump on origin release)
|
|
14
14
|
- **TTLs**: probe 24 h, Phase 1 24 h, Phase 2 7 d
|
|
15
15
|
|
|
16
16
|
## What it caches
|
|
@@ -23,7 +23,7 @@ CODEX_ORIGIN_URL = "https://codex-pdf-lint-sidecar-production.up.railway.app"
|
|
|
23
23
|
# Codex package VERSION at deploy time. MUST match the origin's
|
|
24
24
|
# `codex_pdf.version.VERSION` so KV keys line up. Bump on every
|
|
25
25
|
# origin release.
|
|
26
|
-
CODEX_VERSION = "1.7.
|
|
26
|
+
CODEX_VERSION = "1.7.2"
|
|
27
27
|
# TTL (seconds) for cached SSE event payloads.
|
|
28
28
|
PROBE_TTL = "86400" # 24 h — small payload, refresh daily
|
|
29
29
|
PHASE1_TTL = "86400" # 24 h — matches origin Redis TTL
|
|
@@ -214,9 +214,6 @@ def _polygon_corners(box: Box) -> tuple[Point, Point, Point, Point]:
|
|
|
214
214
|
)
|
|
215
215
|
|
|
216
216
|
|
|
217
|
-
_SCALE = 1_000 # pyclipr integer scale factor for offset operations
|
|
218
|
-
|
|
219
|
-
|
|
220
217
|
def polygon_offset(
|
|
221
218
|
path: Path,
|
|
222
219
|
distance: float,
|
|
@@ -276,7 +273,11 @@ def polygon_offset(
|
|
|
276
273
|
for ring in path.rings:
|
|
277
274
|
scaled = _scale_polygon(ring)
|
|
278
275
|
po.addPath(scaled, jt, et)
|
|
279
|
-
|
|
276
|
+
# Coords are scaled into integer space by `_scale_polygon` (×_CLIPPER_SCALE);
|
|
277
|
+
# the offset distance MUST use the same factor or it gets diluted by the
|
|
278
|
+
# ratio. Prior to 1.7.2 this used a private 1_000 constant that left a 1000×
|
|
279
|
+
# gap, so a 10-pt request only grew by 0.01 pt.
|
|
280
|
+
result_paths = po.execute(distance * _CLIPPER_SCALE)
|
|
280
281
|
rings = [_unscale_polygon(p) for p in result_paths]
|
|
281
282
|
return Path(rings=tuple(rings))
|
|
282
283
|
|
|
@@ -140,27 +140,36 @@ def test_polygon_intersect_triangles_via_clipper() -> None:
|
|
|
140
140
|
|
|
141
141
|
@pytest.mark.skipif(not HAS_PYCLIPR, reason="pyclipr is required for polygon offset")
|
|
142
142
|
def test_polygon_offset_triangle_spread_and_choke() -> None:
|
|
143
|
-
"""
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
143
|
+
"""Triangle offset returns correctly-sized rings.
|
|
144
|
+
|
|
145
|
+
Covers two bugs the pre-1.7.x codex had:
|
|
146
|
+
|
|
147
|
+
1. ``ClipperOffset(miterLimit=...)`` raised ``TypeError`` under pyclipr
|
|
148
|
+
0.1.8 (constructor dropped all kwargs). Triggered only on non-
|
|
149
|
+
rectangular paths because rect inputs hit the fast-path bypass.
|
|
150
|
+
2. The integer-scale factor used for the offset distance (1e3) didn't
|
|
151
|
+
match the coord scale (1e6), so the effective offset was ×1000
|
|
152
|
+
smaller than the caller asked for — a 10-pt request grew the bbox
|
|
153
|
+
by ~0.01 pt. Assertions below check magnitude, not just direction,
|
|
154
|
+
to catch a future re-introduction.
|
|
150
155
|
"""
|
|
151
156
|
triangle = Path.from_polygons([[(0.0, 0.0), (100.0, 0.0), (50.0, 100.0)]])
|
|
152
157
|
|
|
153
158
|
spread = polygon_offset(triangle, 10.0)
|
|
154
159
|
assert len(spread.rings) == 1
|
|
155
160
|
sb = spread.bbox()
|
|
156
|
-
|
|
157
|
-
|
|
161
|
+
# A 10-pt spread should push the bbox at least ~9 pt outward on each
|
|
162
|
+
# side; miter-join geometry on a sharp triangle apex may extend the y
|
|
163
|
+
# max even further, so we only bound the *minimum* growth.
|
|
164
|
+
assert sb.x0 <= -9.0 and sb.y0 <= -9.0, f"spread bbox not wide enough: {sb}"
|
|
165
|
+
assert sb.x1 >= 109.0 and sb.y1 >= 109.0, f"spread bbox not tall enough: {sb}"
|
|
158
166
|
|
|
159
167
|
choke = polygon_offset(triangle, -5.0)
|
|
160
168
|
assert choke.rings
|
|
161
169
|
cb = choke.bbox()
|
|
162
|
-
|
|
163
|
-
assert cb.
|
|
170
|
+
# 5-pt choke should pull each side inward by ≥ ~4 pt.
|
|
171
|
+
assert cb.x0 >= 4.0 and cb.y0 >= 4.0, f"choke bbox not inset enough: {cb}"
|
|
172
|
+
assert cb.x1 <= 96.0 and cb.y1 <= 96.0, f"choke bbox not inset enough: {cb}"
|
|
164
173
|
|
|
165
174
|
|
|
166
175
|
# ---------------------------------------------------------------------------
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|