Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
c203a61
Add CanvasNet.Pptx Phase 1a: OOXML package layer scaffold
Oct 2, 2026
ef2a9f0
Implement PPTX Phase 1b: presentation/theme/master/layout/slide model…
Oct 2, 2026
92cbf18
fix(reqstream): link orphaned Phase 1b theme/placeholder requirements…
Oct 2, 2026
9dd6c89
Implement PPTX Phase 1c: DrawingML shape geometry and paint
Oct 3, 2026
5d807bc
feat(pptx): implement Phase 1d text layout and rendering
Oct 4, 2026
b61de67
docs(pptx): add Phase 1d companion artifacts for text layout and rend…
Oct 4, 2026
d4e6ab6
Harden PPTX OPC package layer (PR #33 review findings 1-6, 15)
Oct 4, 2026
0ca9721
Validate slide relationship type and slide-dimension overflow (PR #33…
Oct 4, 2026
a64acd2
Use InvalidDataException consistently for malformed geometry/paint/co…
Oct 4, 2026
7e39ef3
Add regression tests for PR #33 review findings; restructure system i…
Oct 4, 2026
5f0012a
Update PPTX docs/reqstream/verification/SysML2 to reflect current Pha…
Oct 4, 2026
7ac1c99
fix(pptx): address 7 PR #33 review findings in CanvasNet.Pptx
Oct 4, 2026
3cba02b
Fix word-wrap incorrectly splitting a word across formatting runs (PR…
Oct 4, 2026
b303eeb
docs: document SystemFontCatalog thread-safety guarantees
Oct 4, 2026
9dcbfa4
Add PPTX Phase 1e: picture (p:pic) image rendering
Oct 4, 2026
2483903
Add PPTX Phase 1e: a:tbl table rendering inside p:graphicFrame
Oct 4, 2026
a87b703
Add PPTX Phase 1e: recursive p:grpSp shape-tree parsing and docs
Oct 4, 2026
843dc4b
Add PptxDocument.Render public slide-rendering API (Phase 1f)
Oct 4, 2026
80cbd0e
Document PptxDocument Render public API (Phase 1f)
Oct 4, 2026
86b8819
Fix stale present-tense Render API deferral wording and Phase 1a-1f r…
Oct 4, 2026
b586f14
Add PPTX real-world fixture corpus and smoke-test suite
Oct 4, 2026
84b6830
Fix text alignment positioning under wrap="none"
Oct 4, 2026
7b0ecf7
Fix placeholder xfrm/geometry inheritance past an empty spPr
Oct 4, 2026
94464ce
Document PPTX Phase 2 corpus hardening pass
Oct 4, 2026
872bd2f
Fix curvedUpArrow preset geometry crash and add sibling curved-arrow …
Oct 4, 2026
074328b
Fix Section Header title font-size inheritance for omitted-type place…
Oct 4, 2026
e5a8f5a
Add subtitle autofit investigation regression test
Oct 4, 2026
24ea6b0
Document Section Header font-size fix and subtitle autofit investigation
Oct 4, 2026
1d46926
Add 10 curated real-world PPTX fixtures with licensing
Oct 4, 2026
575a66d
Add corpus smoke tests for new PPTX fixtures
Oct 4, 2026
642062e
Update reqstream/verification/design docs for new PPTX fixtures
Oct 4, 2026
eb49eea
Fix empty <a:lstStyle/> blocking layout/master font-size inheritance
Oct 4, 2026
cfa4b05
Add regression tests for empty lstStyle level-override fallthrough
Oct 4, 2026
bbe7fe3
Document the lstStyle level-override inheritance fix and requirement
Oct 4, 2026
a8c7b28
Model <p:bg> background fill and theme bgFillStyleLst on master/layou…
Oct 4, 2026
f2d3274
Resolve and paint slide/layout/master <p:bg> background fill before s…
Oct 4, 2026
590f08c
Add pixel-level and resolver-level tests for <p:bg> background fill
Oct 4, 2026
d657ca4
Document slide/layout/master background fill (<p:bg>) feature
Oct 4, 2026
95f91cf
feat(pptx): render non-placeholder master/layout decorative shapes
Oct 4, 2026
b212c70
test(pptx): add pixel-level coverage for master/layout shape rendering
Oct 4, 2026
3224073
docs(pptx): document master/layout decorative shape rendering
Oct 4, 2026
d82390e
fix(pptx): prevent master/layout shape failures from aborting slide r…
Oct 4, 2026
2af7c5f
test(pptx): add regression coverage for master/layout shape skip and …
Oct 4, 2026
e89480f
docs(pptx): document master/layout shape graceful-skip and SVG-only i…
Oct 4, 2026
2808781
fix(canvas): alpha-blend composited images instead of raw overwrite
Oct 5, 2026
a63d663
test(canvas): add Porter-Duff alpha compositing regression tests
Oct 5, 2026
e759fce
docs: document alpha-blended image compositing fix
Oct 5, 2026
8871bed
feat(pptx): render bullet and numbering glyphs for text paragraphs
Oct 5, 2026
dd282de
test(pptx): add bullet/numbering parsing, inheritance, and rendering …
Oct 5, 2026
f90a2a9
docs(pptx): document bullet/numbering rendering (Phase 2 Follow-Up)
Oct 5, 2026
bdf615b
fix(pptx): suppress bullets on sldNum/dt/ftr placeholders
Oct 5, 2026
4dfff15
fix(pptx): narrow sldNum/dt/ftr bullet exclusion to master tier only
Oct 5, 2026
495235c
fix(pptx): respect clrMap/clrMapOvr when resolving bg/tx scheme colors
Oct 5, 2026
a2df1e3
feat(pptx): resolve p:style fillRef/lnRef shape style references
Oct 5, 2026
f959cd8
fix(pptx): suppress bullet glyphs on run-less/spacer paragraphs
Oct 5, 2026
4d7ca19
chore(pptx): add PptxColorMapTests.cs to reviewmark review-set coverage
Oct 5, 2026
a0dc69f
feat(pptx): render p:cxnSp connector shapes with arrowheads
Oct 5, 2026
230b4da
fix(pptx): fall back to style lnRef color for fill-less a:ln elements
Oct 5, 2026
038bb77
test(pptx): cover a:ln style-color fallback for fill-less line elements
Oct 5, 2026
15be59b
docs(pptx): document a:ln style-color fallback behavior and default
Oct 5, 2026
d01f361
fix(pptx): default missing a:ln width to PowerPoint's 9525 EMU stroke…
Oct 5, 2026
e4f2c5f
test(pptx): cover default missing-width a:ln resolution and ellipse r…
Oct 5, 2026
5bc990f
docs(pptx): document a:ln default missing-width stroke behavior
Oct 5, 2026
27175ca
fix(drawing): make StrokeOutliner inner-ring collapse tolerance scale…
Oct 5, 2026
68d525b
fix(pptx): stroke shape outlines with a scale-aware flatten tolerance
Oct 5, 2026
41ae58d
docs: document stroke-outliner false-collapse fix and companion requi…
Oct 5, 2026
246c9f0
fix(pptx): clamp bulleted text start-X to clear bullet glyph width
Oct 5, 2026
c371af8
docs(pptx): document bullet/text gutter-clearance fix
Oct 5, 2026
a97e141
fix(pptx): reserve minimum trailing gap after buAutoNum bullet markers
Oct 5, 2026
fcc3e47
fix(text): resolve glyph fallback per-character instead of once per run
Oct 5, 2026
4a91ab3
fix(pptx): render underline styles for <a:rPr u="..."> text runs
Oct 5, 2026
4749574
fix(pptx): clip p:pic images to non-rect prstGeom presets
Oct 5, 2026
df93c97
docs(pptx): document picture preset-geometry clipping
Oct 5, 2026
0128310
test(pptx): harden near-square ellipse picture-clip regression coverage
Oct 5, 2026
265c15f
fix(pptx): render p:pic own ln stroke outline for preset/custom geometry
Oct 5, 2026
2a1905e
fix(pptx): resolve and apply referenced table styles for fill/banding…
Oct 5, 2026
f756b76
Fix PPTX literal-tab rendering to expand to default tab stops
Oct 5, 2026
c6c7835
docs(pptx): fix arithmetic typo in tab-stop wrap-decision test comment
Oct 5, 2026
8678b7c
fix(pptx): harden validation for 7 PR #33 review findings
Oct 5, 2026
a681d5a
Bound GetPartBytes decompressed size to prevent zip-bomb media parts
Oct 5, 2026
03a85a3
fix(pptx): harden table cell-rect merge compensation, size merged-cel…
Oct 5, 2026
9e6205f
Fix pptx text layout: paragraph spacing, whitespace-only lines, gutte…
Oct 5, 2026
934268d
Fix: contain unsupported graphicFrame parse failures in master/layout…
Oct 5, 2026
3f66a9e
fix(drawing): make StrokeOutliner collapse tolerance per-edge/density…
Oct 5, 2026
51a1ac9
docs(pptx): fix stale Phase 1d documentation, document Phase 1e/1f scope
Oct 5, 2026
fdd6082
Fix non-finite/malformed float validation in Pptx parsing (Connectors…
Oct 5, 2026
74f3834
docs(pptx): fix round-2 stale deferred-feature claims (bullets/number…
Oct 5, 2026
42b7134
fix(pptx): render <a:fld> auto-text fields (e.g. slide-number) using …
Oct 5, 2026
2b2f38d
Implement picture fill (<a:blipFill>) support for shape/paragraph fills
Oct 6, 2026
112c671
feat(pptx): implement preset pattern fill (<a:pattFill>) support
Oct 6, 2026
83698eb
Add Phase 1 of DemaConsulting.CanvasNet.Charts library (model + build…
Oct 6, 2026
3cb0a6d
Add ChartRenderer: Phase 2 of DemaConsulting.CanvasNet.Charts
Oct 6, 2026
9abe4ee
Add OpenXmlChartParser: Phase 3 of DemaConsulting.CanvasNet.Charts
Oct 6, 2026
f5d76e6
Integrate chart rendering into PptxDocument (Phase 4 of Charts plan)
Oct 6, 2026
deaff53
Phase 5: finalize CanvasNetCharts documentation and traceability
Oct 6, 2026
b9ecdf7
fix(charts): cap c:ptCount to prevent OOM from crafted chart XML
Oct 6, 2026
58fbd11
fix(charts): guard malformed numeric XML casts in OpenXmlChartParser
Oct 6, 2026
d1d536d
fix(pptx): guard malformed numeric XML casts in geometry/paint/text p…
Oct 6, 2026
8002c8f
test(charts): add malformed-numeric-value regression tests for OpenXm…
Oct 6, 2026
45e534e
fix(pdf): harden 3 CanvasNetPdf-PdfDocument review findings
Oct 6, 2026
63881db
test(pptx): add malformed-numeric-value regression tests for geometry…
Oct 6, 2026
b3ca0c4
fix(pptx): cap nested group-shape recursion depth to prevent stack ov…
Oct 6, 2026
6f1e33a
docs(pptx): reword comments to avoid cspell dictionary additions
Oct 6, 2026
173ba2d
Fix PR review findings: chart cache budget, double-to-float overflow,…
Oct 6, 2026
397969b
Fix documentation staleness flagged in PR review
Oct 6, 2026
973b346
Fix reqstream traceability: stale test references and missing require…
Oct 6, 2026
c9c09fd
Fix PR review findings: chart range overflow, palette immutability, s…
Oct 6, 2026
5d04ffd
Require chart namespace when classifying plot area chart-type elements
Oct 6, 2026
7a1418e
Fix PR review findings: picture surface disposal, chart range overflo…
Oct 6, 2026
5112698
Fix PR review findings: concurrency-safe render image tracking, palet…
Oct 6, 2026
89de46f
Fix PR review findings: document non-thread-safety, immutable palette…
Oct 7, 2026
4fe3605
Add test proving slide-level picture background fill works; correct P…
Oct 7, 2026
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
51 changes: 51 additions & 0 deletions .cspell.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ words:
- combinators
- CSUM
- Decodability
- DOTLESS
- dequantize
- dequantizes
- Deflate
Expand Down Expand Up @@ -97,6 +98,19 @@ words:
- gAMA
- Grayscale
- grayscale
- gridline
- gridlines
- horz
- Horz
- Dmnd
- patt
- pythonpptx
- slidenum
- xfrm
- drawingml
- Calibri
- unoverridden
- subtable
- IDAT
- IDCT
- IEND
Expand All @@ -114,8 +128,10 @@ words:
- mcus
- microarchitecture
- misdecoded
- misrender
- nameof
- nonzero
- paintable
- NOTAFONT
- NOTAGIF
- Outliner
Expand Down Expand Up @@ -309,6 +325,41 @@ words:
- thinspace
- Thinspace
- subsetted
- rels
- Rels
- Linq
- OOXML
- openxmlformats
- officedocument
- presentationml
- pptx
- Pptx
- autofit
- Autofit
- unrotated
- unflipped
- unshifted
- autoshape
- Autoshape
- autoshapes
- Autonumber
- srgb
- MCMXCIV
- hlink
- Hlink
- clrmap
- clrmapovr
- colormap
- openxml
- textless
- aiden
- misrouting
- parameterless
- Lbls
- texel
- precomputes
- uncontained
- prst

# Exclude common build artifacts, dependencies, and vendored third-party code
ignorePaths:
Expand Down
232 changes: 232 additions & 0 deletions .reviewmark.yaml

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions CanvasNet.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
<Project Path="src/DemaConsulting.CanvasNet/DemaConsulting.CanvasNet.csproj" />
<Project Path="src/DemaConsulting.CanvasNet.Svg/DemaConsulting.CanvasNet.Svg.csproj" />
<Project Path="src/DemaConsulting.CanvasNet.Pdf/DemaConsulting.CanvasNet.Pdf.csproj" />
<Project Path="src/DemaConsulting.CanvasNet.Pptx/DemaConsulting.CanvasNet.Pptx.csproj" />
<Project Path="src/DemaConsulting.CanvasNet.Charts/DemaConsulting.CanvasNet.Charts.csproj" />
</Folder>
<Folder Name="/test/">
<Project Path="test/DemaConsulting.CanvasNet.Tests/DemaConsulting.CanvasNet.Tests.csproj" />
<Project Path="test/DemaConsulting.CanvasNet.Svg.Tests/DemaConsulting.CanvasNet.Svg.Tests.csproj" />
<Project Path="test/DemaConsulting.CanvasNet.Pdf.Tests/DemaConsulting.CanvasNet.Pdf.Tests.csproj" />
<Project Path="test/DemaConsulting.CanvasNet.Pptx.Tests/DemaConsulting.CanvasNet.Pptx.Tests.csproj" />
<Project Path="test/DemaConsulting.CanvasNet.Charts.Tests/DemaConsulting.CanvasNet.Charts.Tests.csproj" />
</Folder>
</Solution>
74 changes: 74 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ image operations using `Span<T>`, and supports independent-copy cropping for loa
TrueType text to a surface, automatically substituting a matching system font (or a bundled
Liberation Sans/Serif/Mono font) for text using a non-embedded font (ships as the separate
`DemaConsulting.CanvasNet.Pdf` package)
- 📊 **Chart Rendering** - Build a validated Bar/Column/Line/Area/Pie/Doughnut chart (with axes,
legend, title, and data labels) via a fluent builder and paint it onto a surface with documented
default styling and a categorical color palette (ships as the separate
`DemaConsulting.CanvasNet.Charts` package)
- 📈 **OOXML Chart Parsing** - Parse a raw ECMA-376 DrawingML-Charts `c:chartSpace`/`c:chart` XML
element (for example, a `chart1.xml` OPC part) into a validated chart, reading only cached
values, with no OPC/ZIP packaging or host document-format knowledge (ships as part of the same
`DemaConsulting.CanvasNet.Charts` package). When rendering a `.pptx` presentation via the
separate `DemaConsulting.CanvasNet.Pptx` package's `PptxDocument.Render`, an embedded
`<p:graphicFrame>` chart is automatically parsed and painted using this same package, with no
extra caller code required.
- 🔍 **Header-Only Probing** - `GetInfo` reads headers without decoding pixels (GIF excepted)
- 🖌️ **Path Filling** - Antialiased nonzero/even-odd fill of vector paths
- 🖊️ **Stroke-to-Fill** - Convert stroked paths into fillable outlines
Expand Down Expand Up @@ -92,6 +103,31 @@ Or via Package Manager Console:
Install-Package DemaConsulting.CanvasNet.Pdf
```

Chart rendering requires the separate `DemaConsulting.CanvasNet.Charts` package:

```bash
dotnet add package DemaConsulting.CanvasNet.Charts
```

Or via Package Manager Console:

```powershell
Install-Package DemaConsulting.CanvasNet.Charts
```

PowerPoint (`.pptx`) document parsing and rendering requires the separate
`DemaConsulting.CanvasNet.Pptx` package:

```bash
dotnet add package DemaConsulting.CanvasNet.Pptx
```

Or via Package Manager Console:

```powershell
Install-Package DemaConsulting.CanvasNet.Pptx
```

## Usage

```csharp
Expand Down Expand Up @@ -163,6 +199,44 @@ if (!info.CanDecode)
using var safeSurface = PngCodec.Load("untrusted.png");
```

Building and rendering a chart:

```csharp
using DemaConsulting.CanvasNet.Canvas;
using DemaConsulting.CanvasNet.Charts;

// Build a validated Chart fluently
var chart = new ChartBuilder()
.OfType(ChartType.Column)
.WithCategoryAxis(["Q1", "Q2"])
.WithValueAxis(minimum: 0f, maximum: 10f)
.AddSeries("Revenue", [4.0, 9.0], color: new Rgba32(31, 119, 180, 255))
.WithTitle("Quarterly Revenue")
.WithLegend(ChartLegendPosition.Bottom)
.Build();

// Render it onto a new surface using every rendering default
using var chartSurface = ChartRenderer.Render(chart, 400, 300);
```

Parsing a raw OOXML chart part and rendering it:

```csharp
using DemaConsulting.CanvasNet.Canvas;
using DemaConsulting.CanvasNet.Charts;
using DemaConsulting.CanvasNet.Charts.OpenXml;
using System.Xml.Linq;

// Parse a c:chartSpace/c:chart XML document (for example, a chart1.xml OPC part a host
// document-format library - such as CanvasNetPptx - has already located and opened)
var chartDocument = XDocument.Load("chart1.xml");
var parsedChart = OpenXmlChartParser.Parse(chartDocument);

// The parsed Chart is directly consumable by ChartRenderer, exactly like a Chart built via
// ChartBuilder
using var parsedChartSurface = ChartRenderer.Render(parsedChart, 400, 300);
```

Filling a vector path onto a surface:

```csharp
Expand Down
Loading
Loading