Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
- name: Run guards
run: |
./mvnw -B -ntp clean \
"-Dtest=EnginePdfBoundaryTest,CanonicalTemplateComposerPdfBoundaryTest,PdfRenderInterfaceGuardTest,PdfRenderingSystemECSDispatchTest,DocumentationCoverageTest,DocumentationExamplesTest,CanonicalSurfaceGuardTest,TemplateComposeApiTest,VersionConsistencyGuardTest" \
"-Dtest=EnginePdfBoundaryTest,CanonicalTemplateComposerPdfBoundaryTest,PdfRenderInterfaceGuardTest,DocumentationCoverageTest,DocumentationExamplesTest,CanonicalSurfaceGuardTest,TemplateComposeApiTest,VersionConsistencyGuardTest" \
test

build-and-test:
Expand Down
23 changes: 11 additions & 12 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ When writing new code, avoid Java 21+ APIs and language constructs that don't ex
## Build and test

- The blocking validation gate for repository work is `./mvnw -B -ntp clean verify`.
- Run the guard-focused suite with `./mvnw -B -ntp "-Dtest=EnginePdfBoundaryTest,PdfRenderInterfaceGuardTest,PdfRenderingSystemECSDispatchTest,DocumentationCoverageTest,DocumentationExamplesTest,CanonicalSurfaceGuardTest" test`.
- Run the guard-focused suite with `./mvnw -B -ntp "-Dtest=EnginePdfBoundaryTest,PdfRenderInterfaceGuardTest,DocumentationCoverageTest,DocumentationExamplesTest,CanonicalSurfaceGuardTest" test`.
- Run a focused documentation sanity check with `./mvnw -B -ntp "-Dtest=DocumentationExamplesTest" test`.
- Run the local benchmark wrapper when you change performance-sensitive code or benchmark tooling: `powershell -ExecutionPolicy Bypass -File .\scripts\run-benchmarks.ps1` (Windows). To compare two branches fairly, use `scripts/ab-bench.ps1` (Windows) or the cross-platform `scripts/ab-bench.sh` (Linux/macOS/Git Bash). See [docs/operations/benchmarks.md](./docs/operations/benchmarks.md).

Expand Down Expand Up @@ -183,20 +183,20 @@ not need any of them.
- Engine render markers implement backend-neutral `Render`. Do not
add backend-specific render interfaces back into
`engine/components`.
- PDF rendering logic for the legacy ECS renderer (deprecated; canonical PDF
output goes through `com.demcha.compose.document.backend.fixed.pdf`) lives in
`render-pdf/src/main/java/com/demcha/compose/engine/render/pdf/ecs/handlers/`.
Backend-only helper objects live in
`com.demcha.compose.engine.render.pdf.ecs.helpers`, not in
- PDF rendering logic lives in the canonical fixed-layout backend under
`render-pdf/src/main/java/com/demcha/compose/document/backend/fixed/pdf/handlers/`,
where each `PdfFragmentRenderHandler` draws one fragment kind. Backend-only
helper objects live alongside the backend in
`com.demcha.compose.document.backend.fixed.pdf`, not in
`components/renderable`.
- Builders and layout code get text width and line metrics from
`TextMeasurementSystem`, not from
`LayoutSystem -> RenderingSystem`, `PdfFont`, or PDFBox objects.
- Keep `src/main/java/com/demcha/compose/engine/components/*` free of
`org.apache.pdfbox` and `com.demcha.compose.engine.render.pdf`
imports.
- When you add a new render marker, register its handler in
`PdfRenderingSystemECS` and add or update dispatch coverage.
- When you add a new fragment kind, register its handler with
`PdfFixedLayoutBackend` and add or update dispatch coverage.

Keep the entity core thin:

Expand All @@ -222,8 +222,7 @@ The rules above are enforced by tests:
[DocumentationCoverageTest.java](./src/test/java/com/demcha/documentation/DocumentationCoverageTest.java)
- engine internals guards:
[EnginePdfBoundaryTest.java](./src/test/java/com/demcha/compose/engine/architecture/EnginePdfBoundaryTest.java),
[PdfRenderInterfaceGuardTest.java](render-pdf/src/test/java/com/demcha/compose/engine/render/pdf/PdfRenderInterfaceGuardTest.java),
[PdfRenderingSystemECSDispatchTest.java](render-pdf/src/test/java/com/demcha/compose/engine/render/pdf/ecs/PdfRenderingSystemECSDispatchTest.java)
[PdfRenderInterfaceGuardTest.java](render-pdf/src/test/java/com/demcha/compose/engine/render/pdf/PdfRenderInterfaceGuardTest.java)

## Adding a new feature

Expand Down Expand Up @@ -339,8 +338,8 @@ Choose the smallest tests that match the change:
[PdfRenderInterfaceGuardTest.java](render-pdf/src/test/java/com/demcha/compose/engine/render/pdf/PdfRenderInterfaceGuardTest.java)
- For low-level test harness changes:
[ComponentBuilderTest.java](qa/src/test/java/com/demcha/compose/engine/components/ComponentBuilderTest.java)
- For render-marker dispatch changes:
[PdfRenderingSystemECSDispatchTest.java](render-pdf/src/test/java/com/demcha/compose/engine/render/pdf/ecs/PdfRenderingSystemECSDispatchTest.java)
- For PDF fragment-handler dispatch changes:
[PdfRenderInterfaceGuardTest.java](render-pdf/src/test/java/com/demcha/compose/engine/render/pdf/PdfRenderInterfaceGuardTest.java)
- For layout/positioning behavior:
[ComputedPositionTest.java](./src/test/java/com/demcha/compose/engine/components/layout/ComputedPositionTest.java)
- For pagination and multi-page behavior:
Expand Down
4 changes: 2 additions & 2 deletions docs/architecture/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,8 @@ code should not need any of them.
into the active renderer
- render marker components identify *what* needs to be rendered;
*how* it is drawn lives in renderer-owned handler packages such as
`...render.pdf.ecs.handlers` (with helper objects under
`...render.pdf.ecs.helpers`)
the `PdfFragmentRenderHandler` implementations under
`document.backend.fixed.pdf.handlers`
- `RenderStream` acts as a session factory, not as a per-entity
content-stream opener
- `RenderPassSession` is the shared seam for page lifetime and
Expand Down
3 changes: 1 addition & 2 deletions docs/architecture/package-map.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ per-package artifact.
| `com.demcha.compose.engine.pagination` | Page-breaking helpers and pagination fallback systems. | Maintain child-first ordering and page-shift propagation rules. |
| `com.demcha.compose.engine.measurement` | Text measurement contracts and font-backed implementations. | Builders/layout helpers depend on this seam instead of reaching into renderers. |
| `com.demcha.compose.engine.render` | Backend-neutral render contracts, handler registry, render ordering, and render-pass session lifetime. | Add backend-neutral contracts here, backend-specific drawing elsewhere. |
| `com.demcha.compose.engine.render.pdf` | Shared PDFBox primitives for the canonical fixed-layout backend: `PdfFont`, `GlyphFallbackLogger`, and the header/footer + watermark renderers under `helpers`. | Add canonical-shared PDF support here; the legacy ECS renderer lives in the deprecated `ecs` sub-package. |
| `com.demcha.compose.engine.render.pdf.ecs` | **Deprecated.** Legacy `Entity`-based ECS PDF renderer (`PdfRenderingSystemECS` and collaborators, plus the `ecs.handlers` / `ecs.helpers` sub-packages). | Dead renderer kept only for legacy regression tests; do not extend or optimize. |
| `com.demcha.compose.engine.render.pdf` | Shared PDFBox primitives for the canonical fixed-layout backend: `PdfFont`, `GlyphFallbackLogger`, and the header/footer + watermark renderers under `helpers`. | Add canonical-shared PDF support here; per-fragment PDF drawing lives in the `PdfFragmentRenderHandler` implementations under `document.backend.fixed.pdf.handlers`. |
| `com.demcha.compose.engine.render.word` | Experimental Word backend internals. | Treat as research until a supported public surface is designed. |
| `com.demcha.compose.engine.text` | Internal text hot-path utilities shared by layout and render stages. | Keep helpers backend-neutral and avoid public authoring concepts here. |
| `com.demcha.compose.engine.text.markdown` | Markdown token parsing used by text preparation. | Keep output backend-neutral. |
Expand Down
25 changes: 12 additions & 13 deletions docs/contributing/implementation-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,6 @@ Relevant files:

- [TableBuilder.java](../../render-pdf/src/test/java/com/demcha/compose/testsupport/engine/assembly/TableBuilder.java)
- [TableRow.java](../../src/main/java/com/demcha/compose/engine/components/renderable/TableRow.java)
- [TableCellBox.java](../../render-pdf/src/main/java/com/demcha/compose/engine/render/pdf/ecs/helpers/TableCellBox.java)
- [TableResolvedCell.java](../../src/main/java/com/demcha/compose/engine/components/content/table/TableResolvedCell.java)

Rule of thumb:
Expand Down Expand Up @@ -321,29 +320,29 @@ Preferred extension pattern for new backends:
4. keep backend-only helper drawing in renderer-owned helper packages when the code is not an entity render marker
5. keep renderer ordering policy in the rendering layer rather than in pagination utilities

> **Deprecated reference implementation.** The PDF renderer named below
> (`PdfRenderingSystemECS` and the `engine.render.pdf.ecs` handlers/helpers) is the
> legacy `Entity`-based ECS renderer, kept only for regression tests; canonical PDF
> output is produced by `com.demcha.compose.document.backend.fixed.pdf`. The
> backend-neutral `engine.render` *contracts* (`Render`, `RenderPassSession`,
> `RenderStream`, `EntityRenderOrder`) are **not** deprecatedonly the ECS PDF
> implementation is. Do not extend the `ecs` renderer.
> **Canonical PDF renderer.** Canonical PDF output is produced by
> `com.demcha.compose.document.backend.fixed.pdf`: `PdfFixedLayoutBackend`
> dispatches each layout fragment to a `PdfFragmentRenderHandler` implementation
> under `document.backend.fixed.pdf.handlers`. The backend-neutral `engine.render`
> *contracts* (`Render`, `RenderPassSession`, `RenderStream`, `EntityRenderOrder`)
> remain the shared render seamextend PDF drawing by adding or updating a
> fragment handler, not by touching those contracts.

Important files:

- [Render.java](../../src/main/java/com/demcha/compose/engine/render/Render.java)
- [RenderPassSession.java](../../src/main/java/com/demcha/compose/engine/render/RenderPassSession.java)
- [RenderStream.java](../../src/main/java/com/demcha/compose/engine/render/RenderStream.java)
- [PdfRenderingSystemECS.java](../../render-pdf/src/main/java/com/demcha/compose/engine/render/pdf/ecs/PdfRenderingSystemECS.java)
- [PdfRenderSession.java](../../render-pdf/src/main/java/com/demcha/compose/engine/render/pdf/ecs/PdfRenderSession.java)
- [PdfFixedLayoutBackend.java](../../render-pdf/src/main/java/com/demcha/compose/document/backend/fixed/pdf/PdfFixedLayoutBackend.java)
- [PdfFragmentRenderHandler.java](../../render-pdf/src/main/java/com/demcha/compose/document/backend/fixed/pdf/PdfFragmentRenderHandler.java)
- [EntityRenderOrder.java](../../src/main/java/com/demcha/compose/engine/render/EntityRenderOrder.java)

Migration rule for new engine components:

- implement backend-neutral `Render`, not backend-specific render interfaces
- move PDF drawing into `...render.pdf.ecs.handlers`
- move PDF drawing into a `PdfFragmentRenderHandler` under `...document.backend.fixed.pdf.handlers`
- use `TextMeasurementSystem` for text width and line metrics instead of reaching through `LayoutSystem`
- place PDF-only helper objects in `...render.pdf.ecs.helpers`
- place PDF-only helper objects alongside the backend in `...document.backend.fixed.pdf`
- keep page-surface lifetime in a backend-specific `RenderPassSession`, not in engine builders or render markers
- keep resolved draw ordering in renderer-owned or renderer-neutral rendering helpers such as `EntityRenderOrder`
- register a render handler for every engine render marker because the PDF entity path no longer supports a backend-specific render fallback
Expand All @@ -353,7 +352,7 @@ Migration rule for new engine components:
The current render seam is deliberately narrower than a full backend abstraction. Use these rules when extending it:

- `RenderStream<T>` should create one render-pass session, not one stream per entity
- renderer orchestrators such as `PdfRenderingSystemECS.process(...)` should open one session for the whole pass
- renderer orchestrators such as `PdfFixedLayoutBackend` should open one session for the whole pass
- single-page handlers should use the session-managed page surface directly
- multi-page handlers should request page surfaces explicitly per fragment or page
- page creation or annotation-only work should use the session's page-availability helper instead of opening a dummy drawing surface
Expand Down
23 changes: 0 additions & 23 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -648,29 +648,6 @@
-->
<excludes>
<exclude>com.demcha.compose.document.layout.payloads</exclude>
<!--
Legacy ECS PDF renderer (PdfRenderingSystemECS and its
collaborators), relocated to
com.demcha.compose.engine.render.pdf.ecs[.handlers|.helpers]
and @Deprecated at package level. This is the dead
Entity-based renderer that no public entry point reaches
(canonical PDF output goes through
document.backend.fixed.pdf); it carries no
binary-compatibility promise. Both the relocated packages
and the vacated original fully-qualified names are excluded
so the package split is not flagged as a breaking removal.
-->
<exclude>com.demcha.compose.engine.render.pdf.ecs</exclude>
<exclude>com.demcha.compose.engine.render.pdf.ecs.handlers</exclude>
<exclude>com.demcha.compose.engine.render.pdf.ecs.helpers</exclude>
<exclude>com.demcha.compose.engine.render.pdf.handlers</exclude>
<exclude>com.demcha.compose.engine.render.pdf.PdfRenderingSystemECS</exclude>
<exclude>com.demcha.compose.engine.render.pdf.PdfCanvas</exclude>
<exclude>com.demcha.compose.engine.render.pdf.PdfStream</exclude>
<exclude>com.demcha.compose.engine.render.pdf.PdfFileManagerSystem</exclude>
<exclude>com.demcha.compose.engine.render.pdf.PdfGuidesRenderer</exclude>
<exclude>com.demcha.compose.engine.render.pdf.helpers.TableCellBox</exclude>
<exclude>com.demcha.compose.engine.render.pdf.helpers.PdfBookmarkBuilder</exclude>
<!--
engine.measurement.TextMeasurementSystem dropped its vestigial
SystemECS super-interface (and the no-op process(EntityManager)
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

Loading