Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
4 changes: 4 additions & 0 deletions .cspell.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@ language: en
# Project-specific technical terms and tool names
words:
- Aabb
- functiontype
- Poppler
- AABB
- Adler
- AESV
- pypdf
- udata
- AGG
- apimark
- ApiMark
Expand Down
1 change: 1 addition & 0 deletions .reviewmark.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,7 @@ reviews:
- "src/DemaConsulting.CanvasNet.Pdf/PdfDocument.Functions.cs" # pattern phase 1 (sampled function)
- "src/DemaConsulting.CanvasNet.Pdf/PdfDocument.Patterns.cs" # pattern phase (shared /Pattern dispatch)
- "src/DemaConsulting.CanvasNet.Pdf/PdfDocument.Patterns.Shading.cs" # pattern phase (shading patterns)
- "src/DemaConsulting.CanvasNet.Pdf/PdfDocument.Patterns.Shading.Mesh.cs" # mesh shadings (types 4-7)
- "src/DemaConsulting.CanvasNet.Pdf/PdfDocument.Patterns.Tiling.cs" # pattern phase (tiling patterns)
- "src/DemaConsulting.CanvasNet.Pdf/PdfDocument.FontFallback.cs" # phase 6 unit source (font fallback)
- "src/DemaConsulting.CanvasNet.Pdf/PdfDocument.Text.cs" # phase 4 unit source (text rendering)
Expand Down
31 changes: 17 additions & 14 deletions docs/design/canvas-net-pdf.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,25 +86,26 @@ content stream as a nested, implicitly `q`/`Q`-bracketed execution of the same i
14 replaced the color-space model to add `/CalRGB`, `/ICCBased` (resolved via its `/N` or
`/Alternate`), and `/Indexed` (a palette lookup over any supported base color space), and
introduced the `/Pattern` color space: axial/radial shading patterns (`/PatternType 2`,
`/ShadingType 2`/`3`) reusing a widened Function evaluator that now also supports
`/ShadingType 2`-`7`) reusing a widened Function evaluator that now also supports
`/FunctionType 2` (exponential interpolation) and `/FunctionType 3` (stitching) functions in
addition to `/FunctionType 0` (sampled); and colored/uncolored tiling patterns (`/PatternType 1`,
each cell rendered through the same nested-execution machinery `/Subtype /Form` XObjects use).
Phase 15 added `CCITTFaxDecode` (Group 4/T.6 MMR only) image-XObject decoding. Phases 16/17 added
decryption of a document encrypted with the PDF `/Filter /Standard` security handler using RC4
(`/V 1`/`/V 2`), AES-128 (`/V 4`/`/CFM /AESV2`), or AES-256 using the simpler R5 key derivation
(`/V 5`/`/R 5`/`/CFM /AESV3`), authenticating either the empty user password (the default) or an
(`/V 1`/`/V 2`), AES-128 (`/V 4`/`/CFM /AESV2`), or AES-256 using the R5 or R6 (hardened hash) key derivation
(`/V 5`/`/R 5` or `/R 6`/`/CFM /AESV3`), authenticating either the empty user password (the default) or an
optional caller-supplied password tried as both the user and the owner password. **Current
limitations**: `/MMType1` (Multiple Master Type 1) fonts remain entirely unsupported and fail
closed; `/Encoding` values other than `/Identity-H` (including `/Identity-V` and predefined CJK
encodings) and a CID-keyed CFF program fail closed too; only the `/WinAnsiEncoding`/
`/MacRomanEncoding`/`/StandardEncoding` base encodings (plus `/Differences`) are supported (an
unrecognized base encoding fails closed); fill (`Tr 0`), stroke (`Tr 1`), fill+stroke (`Tr 2`),
and invisible (`Tr 3`) text-rendering modes are supported (clip modes `Tr 4`-`7` fail closed); a
and invisible (`Tr 3`) text-rendering modes and the clip modes (`Tr 4`-`7`) are supported (a Type 3
glyph under a clip mode fails closed); a
Form XObject's `/BBox` is never used to clip its content and its `/Group` (transparency group)
entry is never consulted, though the Form itself renders; `/ShadingType` values other than `2`/`3`
and `/FunctionType 4` (PostScript calculator) functions fail closed, as does the `sh` operator and
general path clipping (`W`/`W*`), both of which are silently skipped rather than rejected; no
entry is never consulted, though the Form itself renders; `/ShadingType` values outside `2`-`7`
and `/FunctionType 4` (PostScript calculator) functions fail closed; the `sh` operator and general
path clipping (`W`/`W*`) are supported; no
`/SMask`/alpha compositing or transparency groups (every decoded image is treated as fully
opaque); no `JPXDecode` filter decoding (fails closed; `CCITTFaxDecode` - Group 4 (T.6 MMR) only -
is supported); `/Separation`/`/DeviceN`/`/CalGray`/`/Lab` color spaces remain unsupported and fail
Expand Down Expand Up @@ -153,7 +154,8 @@ The system exposes the following public API to external consumers, all on the se
validation unwrapped, throws `InvalidDataException` for malformed `/Contents` or a malformed
recognized operator, throws `Codecs.UnsupportedImageFeatureException` for a well-formed but
unsupported color space/stream filter/pattern or shading shape/font subtype or encoding/
text-rendering mode/symbolic-font-without-embedded-data, and throws `ObjectDisposedException`
Type 3 glyph under a clip text-rendering mode (`pdf-text-render-mode-type3-clip`)/
symbolic-font-without-embedded-data, and throws `ObjectDisposedException`
once disposed.
- **PdfDocument.Render(int pageIndex, float dpi)**: Convenience overload preserving the page's
own aspect ratio: reads `GetPageInfo(pageIndex)`'s rotation-adjusted point-space width/height,
Expand Down Expand Up @@ -261,7 +263,7 @@ each with its own consistently-applied behavior:
An `/Encrypt` key present in the trailer is detected explicitly: `PdfDocument` decrypts every
indirect object's strings and every stream's raw bytes before any other parsing logic observes
them, for a document using the PDF `/Filter /Standard` security handler with RC4 (`/V 1`/`/V 2`),
AES-128 (`/V 4`/`/CFM /AESV2`), or AES-256 using the simpler R5 key derivation (`/V 5`/`/R 5`/
AES-128 (`/V 4`/`/CFM /AESV2`), or AES-256 using the R5 or R6 (hardened hash) key derivation (`/V 5`/`/R 5` or `/R 6`/
`/CFM /AESV3`), authenticating either the empty user password (the default) or an optional
caller-supplied password tried as both the user and the owner password. `PdfDocument` never
attempts to interpret the (still-encrypted) bytes of an encrypted document as plaintext content
Expand All @@ -273,8 +275,8 @@ to every well-formed but out-of-scope construct it could then encounter: an unsu
space, an unsupported stream filter, and an unsupported image `/BitsPerComponent` are all
rejected with `Codecs.UnsupportedImageFeatureException` rather than being silently skipped or
mis-rendered. Phase 4 extended the same posture to text/font constructs: a font dictionary's
`/MMType1` subtype, an `/Encoding` naming an unrecognized base encoding, and a clip
text-rendering mode (`Tr 4`-`7`) are all likewise rejected with
`/MMType1` subtype, an `/Encoding` naming an unrecognized base encoding, and (as of the text-clip
change) a Type 3 glyph shown under a clip text-rendering mode (`Tr 4`-`7`) are all likewise rejected with
`Codecs.UnsupportedImageFeatureException`. Phase 6 narrowed (but did not remove) the font-subtype
fail-closed boundary: a `/Subtype /TrueType` font lacking an embedded `/FontFile2` is now resolved
via automatic system/bundled-font substitution rather than rejected outright, except that a
Expand Down Expand Up @@ -328,7 +330,7 @@ descriptive `Feature` string so a caller (or this repository's own tests) can di
which unsupported construct was encountered — the complete current set is:
`pdf-encrypted-filter-{name}` (a non-`/Standard` security handler), `pdf-encrypted-cfm-{name}`
(an unsupported `/CF/StdCF/CFM`), `pdf-encrypted-crypt-filter-{name}` (an unsupported named
crypt filter), `pdf-encrypted-r6-hardened-hash`, `pdf-encrypted-r-{revision}`,
crypt filter), `pdf-encrypted-r-{revision}`,
`pdf-encrypted-v-{version}`, `pdf-encrypted-password-required` (a `null` password when a
non-empty one is genuinely required), `pdf-encrypted-incorrect-password`,
`pdf-encrypted-password-non-ascii` (an R2-R4 password outside ASCII 0-127),
Expand All @@ -343,7 +345,7 @@ font program), `pdf-font-encoding-{name}`, `pdf-font-type0-encoding-{name}` (a `
`/Encoding` other than `/Identity-H`), `pdf-font-cidfonttype-{subtype}` (a descendant `/Subtype`
other than `/CIDFontType2`/`/CIDFontType0`), `pdf-font-fontfile3-unrecognized-shape`,
`pdf-font-tounicode-{operator}` and `pdf-font-tounicode-bfrange-array-destination` (an
unsupported `/ToUnicode` CMap construct), `pdf-text-render-mode-{mode}` (clip),
unsupported `/ToUnicode` CMap construct), `pdf-text-render-mode-type3-clip` (a Type 3 glyph under clip mode),
`pdf-ccittfax-group3`, `pdf-ccittfax-endofline`, and `pdf-ccittfax-colorspace`. `/Annots`
(annotations) and AcroForms are simply not
processed at all — page rendering silently ignores `/Annots` rather than throwing — since this is
Expand Down Expand Up @@ -398,7 +400,8 @@ guards.
a malformed recognized operator's operand count/type, and throws
`Codecs.UnsupportedImageFeatureException` for a well-formed but unsupported color space,
stream filter, pattern/shading shape, function type, or
font subtype/encoding/symbolic-font-without-embedded-data/text-rendering mode
font subtype/encoding/symbolic-font-without-embedded-data/Type 3 glyph under a clip
text-rendering mode (`pdf-text-render-mode-type3-clip`)
4. **Output**: A new `Canvas.Surface` of exactly the requested size, painted with the page's
interpreted path geometry, any placed image XObjects and nested Form XObjects, any
pattern/shading-filled paths, and any shown text (or fully transparent, when the page declares
Expand Down
Loading
Loading