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
48 changes: 48 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# cewe2pdf programming guidance

Read this file before editing. Use the [README documentation map](README.md#documentation) to find the user guide, architecture, test workflow, and implementation rationale.

## Workspace and review

- Work only in the checkout or task worktree authorized by the programmer. Keep generated output there.
- Follow the programmer's review workflow; do not stage, commit, push, merge, publish, or synchronize another checkout without authorization.
- Report the resulting behaviour, verification performed, and unresolved failures or limitations. An incomplete test run is not a passing suite.
- Keep private conversation transcripts, personal paths, and account details out of shared documentation.

## Coding conventions

- Prefer f-strings, including logging, and follow existing names.
- Prefer explicit conditions and product dispatch; avoid chained comparisons where separate conditions are clearer.
- Use one indent level for continuation lines rather than aligning beneath an earlier expression.
- Explain undocumented CEWE conventions, empirical calibration, ownership, and non-obvious Python mechanisms in focused comments.
- Use descriptive domain names; avoid unrelated formatting, consistency renames, and architectural rewrites of working code.
- Follow the repository's flake8/pylint configuration. Use narrow, explained suppressions rather than distorting a design to satisfy a metric.

## Platforms and file integrity

- Support normal Python execution on Windows, Linux, and macOS. Guard Windows-only imports and integration.
- Verify the interpreter and use the [supported environment setup](README.md#install); do not assume a particular local environment name or path.
- Write shared Markdown as UTF-8. Follow repository attributes and explicit local text-file conventions; otherwise preserve existing line endings.
- CRLF is a local Windows preference, not a requirement for all contributors. Avoid unrelated newline changes and preserve binary resources byte-for-byte.
- Use platform-aware paths and resource discovery. Close temporary files and database connections before reopening, replacing, or cleaning them.

## Changes and verification

- Make small, reviewable changes. Preserve established `convertMcf` behaviour unless deliberately changing it.
- Derive behaviour from MCF structure, resources, and controlled editor comparisons. Establish a general rule before adding special cases or calibration factors.
- Reuse shared rendering, font, and resource mechanisms. Respect the [architecture and ownership boundaries](documents/DEVELOPER_GUIDE.md#conversion-model); avoid conversion-time mutable globals.
- Follow the [test workflow](tests/README.md), including focused checks, linting, and full regression verification for code changes. Documentation-only changes need encoding, link, and content checks.
- Generate candidate PDFs for review; the programmer approves replacement results. Never promote a candidate simply to make tests pass.
- Follow the [cleanup procedure](tests/README.md#cleaning-up-temporary-files), protecting approved results and album resources. Preserve outputs requested for inspection.

## Documentation ownership

Keep detailed information in its authoritative home and link to it:
- [README](README.md): installation, configuration, usage, and supported features.
- [Developer guide](documents/DEVELOPER_GUIDE.md): architecture, dependency maintenance, diagnostics, and versioning.
- [Tests](tests/README.md): execution, fixture conventions, approval, and cleanup.
- [Build guide](documents/build_a_compiled_version.md): executable builds and Windows integration.
- [Project context](documents/PROJECT_CONTEXT.md): rationale behind non-obvious implementation choices.
- [History](documents/history/README.md): superseded notes, not current instructions.

Update the relevant document when changing behaviour. Format-specific notes stay beside their implementation.
420 changes: 116 additions & 304 deletions README.md

Large diffs are not rendered by default.

36 changes: 25 additions & 11 deletions cewe2pdf.pyproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,27 @@
<Content Include=".gitignore" />
<Content Include=".pylintrc" />
<Content Include="additional_fonts.example.txt" />
<Content Include="documents\build_a_compiled_version.md" />
<Content Include="documents\PROJECT_CONTEXT.md" />
<Content Include="AGENTS.md" />
<Content Include="documents\history\source-reorganization-2026.md" />
<Content Include="documents\history\clp-decoding-notes-2020.md" />
<Content Include="documents\history\unittest_fotobook-windows-notes.md" />
<Content Include="documents\history\build_a_compiled_version-2024.md" />
<Content Include="documents\history\environments\README.md" />
<Content Include="documents\history\README.md" />
<Content Include="assets\cewe2pdf-icon.ico" />
<Content Include="assets\cewe2pdf-icon.png" />
<Content Include="cewe2pdf.spec" />
<Content Include="clipart\CLP file format.txt" />
<Content Include="clipart\CLP_FILE_FORMAT.md" />
<Content Include="clipart\__pycache__\areas.cpython-312.pyc" />
<Content Include="clipart\__pycache__\catalog.cpython-312.pyc" />
<Content Include="clipart\__pycache__\clpfile.cpython-312.pyc" />
<Content Include="clipart\__pycache__\__init__.cpython-312.pyc" />
<Content Include="DEVELOPER_GUIDE.md" />
<Content Include="documents\mcf_feature_classification.md" />
<Content Include="documents\readme.txt" />
<Content Include="environments\cewe2pdfenvlinux.yml" />
<Content Include="environments\cewe2pdfenvwindows.yml" />
<Content Include="environments\environments.md" />
<Content Include="documents\DEVELOPER_GUIDE.md" />
<Content Include="documents\history\mcf_feature_classification.md" />
<Content Include="documents\history\environments\cewe2pdfenvlinux.yml" />
<Content Include="documents\history\environments\cewe2pdfenvwindows.yml" />
<Content Include="LICENSE" />
<Content Include="pytest.ini" />
<Content Include="requirements-pinned.txt" />
Expand Down Expand Up @@ -167,7 +174,7 @@
<Content Include="loggerconfig.yaml" />
<Content Include="README.md" />
<Content Include="requirements.txt" />
<Content Include="TestingOnWSL.md" />
<Content Include="documents\TestingOnWSL.md" />
<Content Include="tests\Resources\photofun\fonts\Poppins\OFL.txt" />
<Content Include="tests\Resources\photofun\fonts\Stafford Bold Italic.ttf" />
<Content Include="tests\Resources\photofun\fonts\Stafford Bold.ttf" />
Expand Down Expand Up @@ -303,7 +310,7 @@
<Content Include="tests\hps\5026\addons\125186\masks\v1\decorations\12809-DECO-ZZ.xml" />
<Content Include="tests\hps\5026\addons\63488\cliparts\v1\decorations\rect_cream.clp" />
<Content Include="tests\hps\5026\addons\63488\cliparts\v1\decorations\rect_cream.xml" />
<Content Include="tests\ReadMe.txt" />
<Content Include="tests\README.md" />
<Content Include="tests\Resources\config\keyaccount.xml" />
<Content Include="tests\Resources\photofun\backgrounds\201.jpg" />
<Content Include="tests\Resources\photofun\backgrounds\448.jpg" />
Expand Down Expand Up @@ -469,6 +476,10 @@
<Compile Include="tests\testShadows\test_shadows.py" />
<Compile Include="tests\testTabs\test_tabs.py" />
<Compile Include="tests\testTextArt\test_textart.py" />
<Compile Include="tests\testTextArt\test_textartBackground.py" />
<Compile Include="tests\testTextArt\test_textartPlacement.py" />
<Compile Include="tests\testTextArt\test_textartSpacing.py" />
<Compile Include="tests\testTextArt\test_textartShadow.py" />
<Compile Include="tests\testTextBox\test_textBox.py" />
<Compile Include="tests\testTextLinks\test_links.py" />
<Compile Include="tests\testTextLinks\test_textLinks.py" />
Expand All @@ -485,10 +496,12 @@
</Compile>
<Compile Include="texts\areas.py" />
<Compile Include="texts\art.py" />
<Compile Include="texts\backgrounds.py" />
<Compile Include="texts\lists.py" />
<Compile Include="texts\markup.py" />
<Compile Include="texts\outlines.py" />
<Compile Include="texts\spacing.py" />
<Compile Include="texts\shadows.py" />
<Compile Include="texts\tabs.py" />
<Compile Include="texts\__init__.py" />
</ItemGroup>
Expand All @@ -501,7 +514,8 @@
<Folder Include="clipart\__pycache__\" />
<Folder Include="decorations\" />
<Folder Include="documents\" />
<Folder Include="environments\" />
<Folder Include="documents\history\" />
<Folder Include="documents\history\environments\" />
<Folder Include="fonts\" />
<Folder Include="indexing\" />
<Folder Include="infrastructure\" />
Expand Down Expand Up @@ -689,4 +703,4 @@
<Output TaskParameter="Command" ItemName="Commands" />
</CreatePythonCommandItem>
</Target>
</Project>
</Project>
97 changes: 0 additions & 97 deletions clipart/CLP file format.txt

This file was deleted.

73 changes: 73 additions & 0 deletions clipart/CLP_FILE_FORMAT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# CLP encoding and custom resources

Copyright (c) 2020 by BarchSteel

The [original decoding investigation](../documents/history/clp-decoding-notes-2020.md)
records how the format was identified. This document owns the current decoding and
resource-authoring notes; the encoding is not encryption.

## Encoding and decoding

A CLP file begins with `a`, followed by a hexadecimal representation of SVG bytes.
Delivered files can intersperse extra lowercase letters outside the hexadecimal range.
The reader checks the prefix, discards `g` through `z`, and decodes the remaining hex.
Use [ClpFile](clpfile.py) rather than maintaining a second parser.

## Using custom clip-art files

You can use your own .clp files in the CEWE software, but it is not known if
this will work if you really order a photo book with custom clip-art. You have
been warned.

Older CEWE versions used a catalogue file called 'cliparts_default.xml'. That
file is no longer present in current installations: CEWE scans the resource
folders instead. For example, a Windows installation using account 5026 stores
its downloaded decorations below:

%LOCALAPPDATA%\CEWE\hps\5026\photofun\decorations

Use a unique numeric designElementId, place an XML descriptor and the .clp
files in their own folder below that location, and restart CEWE. The editor
can search for the numeric ID directly. XML descriptors name files with an
'.svg' extension even when the installed files are .clp.

## Creating custom passepartouts (masks and frames)

A passepartout is a 'fading' decoration with:

* an XML descriptor;
* a mask .clp, which defines the visible shape of the photograph;
* a frame/clip .clp, which is painted above the photograph; and
* optionally, a preview .clp for CEWE's decoration picker.

For example, the descriptor has this shape:

<decoration type="fading" designElementId="990001" id="example-frame">
<categories><category>category-travel</category></categories>
<fading designElementType="passepartout" file="example-mask.svg"
keepAspectRatio="1" ratio="0.8056">
<clipart file="example-clip.svg" designElementType="clipart" ratio="0.8056"/>
<fotoarea height="0.57" width="0.83" x="0.085" y="0.285"/>
</fading>
</decoration>

There is an important geometry convention. The frame/clip SVG canvas covers
the complete passepartout and must have the aspect ratio declared by 'ratio'.
The mask SVG canvas covers only the photograph aperture and must have the
aspect ratio implied by 'fotoarea', not the full frame. If these canvases are
made square by default, CEWE may display the frame but cewe2pdf will not
interpret the mask and frame consistently.

The helper in this repository writes the simple CLP encoding:

ClpFile.convertSVGtoCLP('example-mask.svg')

Keep the editable SVG source outside the installed resource folder, then place
the resulting .clp files beside the XML descriptor. Validate the resource in
the CEWE editor first. Once accepted, copy the exact resource tree into a
self-contained test fixture, for example:

tests/hps/5026/photofun/decorations/<designElementId>/<resource-name>/

Test INI files can point 'hpsFolder' at 'tests/hps', ensuring that cewe2pdf
uses the fixture rather than a developer's installed CEWE content.
Loading
Loading