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
12 changes: 12 additions & 0 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"fallout.cli": {
"version": "11.0.18",
"commands": [
"fallout"
]
}
}
}
145 changes: 145 additions & 0 deletions .fallout/build.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"Host": {
"type": "string",
"enum": [
"AppVeyor",
"AzurePipelines",
"Bamboo",
"Bitbucket",
"Bitrise",
"GitHubActions",
"GitLab",
"Jenkins",
"Rider",
"SpaceAutomation",
"TeamCity",
"Terminal",
"TravisCI",
"VisualStudio",
"VSCode"
]
},
"ExecutableTarget": {
"type": "string",
"enum": [
"Clean",
"Compile",
"CreatePackage",
"Default",
"Package",
"PrePublish",
"Publish",
"PublishPackage",
"PublishPreRelease",
"PublishRelease",
"Restore",
"RunUnitTests"
]
},
"Verbosity": {
"type": "string",
"description": "",
"enum": [
"Verbose",
"Normal",
"Minimal",
"Quiet"
]
},
"FalloutBuild": {
"properties": {
"Continue": {
"type": "boolean",
"description": "Indicates to continue a previously failed build attempt"
},
"Help": {
"type": "boolean",
"description": "Shows the help text for this build assembly"
},
"Host": {
"description": "Host for execution. Default is 'automatic'",
"$ref": "#/definitions/Host"
},
"NoLogo": {
"type": "boolean",
"description": "Disables displaying the NUKE logo"
},
"Partition": {
"type": "string",
"description": "Partition to use on CI"
},
"Plan": {
"type": "boolean",
"description": "Shows the execution plan (HTML)"
},
"Profile": {
"type": "array",
"description": "Defines the profiles to load",
"items": {
"type": "string"
}
},
"Root": {
"type": "string",
"description": "Root directory during build execution"
},
"Skip": {
"type": "array",
"description": "List of targets to be skipped. Empty list skips all dependencies",
"items": {
"$ref": "#/definitions/ExecutableTarget"
}
},
"Target": {
"type": "array",
"description": "List of targets to be invoked. Default is '{default_target}'",
"items": {
"$ref": "#/definitions/ExecutableTarget"
}
},
"Verbosity": {
"description": "Logging verbosity during build execution. Default is 'Normal'",
"$ref": "#/definitions/Verbosity"
},
"BuildProjectFile": {
"type": [
"null",
"string"
],
"description": "Path to the build project (.csproj) relative to the repository root. Defaults to 'build/_build.csproj' when unset. Read by the Fallout global tool's in-tool runner."
}
}
}
},
"allOf": [
{
"properties": {
"AngleSharpVersion": {
"type": "string",
"description": "AngleSharp package version override (e.g. 1.0.0 for compatibility checks)"
},
"Configuration": {
"type": "string",
"enum": [
"Debug",
"Release"
],
"description": "Configuration to build - Default is 'Debug' (local) or 'Release' (server)"
},
"ReleaseNotesFilePath": {
"type": "string",
"description": "ReleaseNotesFilePath - To determine the SemanticVersion"
},
"Solution": {
"type": "string",
"description": "Path to a solution file that is automatically loaded"
}
}
},
{
"$ref": "#/definitions/FalloutBuild"
}
]
}
4 changes: 4 additions & 0 deletions .fallout/parameters.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"$schema": "./build.schema.json",
"Solution": "src/AngleSharp.Renderer.sln"
}
36 changes: 35 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,22 @@ jobs:
npx pilet publish --fresh --url https://feed.piral.cloud/api/v1/pilet/anglesharp --api-key ${{ secrets.PIRAL_FEED_KEY }}

linux:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04

steps:
- uses: actions/checkout@v5

- name: Install deterministic fonts for snapshots
run: |
sudo apt-get update
sudo apt-get install -y fonts-dejavu-core fontconfig
fc-cache -f
fc-match "DejaVu Serif"
fc-match "DejaVu Sans"
fc-match "DejaVu Sans Mono"
fc-list | grep -q "DejaVu Serif"
fc-list | grep -q "DejaVu Sans"
fc-list | grep -q "DejaVu Sans Mono"

- name: Setup dotnet
uses: actions/setup-dotnet@v5
Expand All @@ -57,8 +69,20 @@ jobs:
10.0.x

- name: Build
env:
ANGLESHARP_SNAPSHOT_STRICT: 1
run: ./build.sh -AngleSharpVersion 1.5.0

- name: Upload visual assets
if: always()
uses: actions/upload-artifact@v4
with:
name: linux-visual-assets
path: |
src/AngleSharp.Renderer.Tests/verification-assets/**
src/AngleSharp.Renderer.Tests/failure-assets/**
if-no-files-found: ignore

windows:
runs-on: windows-latest

Expand All @@ -80,3 +104,13 @@ jobs:
} else {
.\build.ps1 -AngleSharpVersion 1.5.0
}

- name: Upload visual assets
if: always()
uses: actions/upload-artifact@v4
with:
name: windows-visual-assets
path: |
src/AngleSharp.Renderer.Tests/verification-assets/**
src/AngleSharp.Renderer.Tests/failure-assets/**
if-no-files-found: ignore
10 changes: 6 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ local.properties
[Dd]ebug/
[Rr]elease/
[Bb]in/
[Bb]uild/
build/bin/
build/obj/
[Oo]bj/

# Visual Studio 2015 cache/options directory
Expand Down Expand Up @@ -171,7 +172,8 @@ Desktop.ini
*.egg
*.egg-info
dist
build
build/bin
build/obj
eggs
parts
var
Expand All @@ -195,5 +197,5 @@ pip-log.txt
# Mac crap
.DS_Store

# Nuke build tool
.nuke/temp
# Fallout build tool
.fallout/temp
74 changes: 74 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# AGENTS.md

Guidance for AI coding agents working in this repository. Keep this file as the quick-start reference for the repo's commands, architecture, conventions, and test workflow.

## What This Repository Is

AngleSharp.Renderer adds rendering capabilities on top of AngleSharp and AngleSharp.Css. The current implementation is a display-list renderer with a SkiaSharp backend that rasterizes HTML/CSS content into PNG images.

## Most Important Commands

Use the solution-level test command for normal validation:

```bash
dotnet test src/AngleSharp.Renderer.sln
```

Use the test project directly when iterating on renderer behavior:

```bash
dotnet test src/AngleSharp.Renderer.Tests/AngleSharp.Renderer.Tests.csproj
```

The repo also includes build scripts that drive the Fallout bootstrapper:

```bash
./build.sh
./build.ps1
./build.cmd
```

The main renderer project targets `net8.0` and `net10.0`. The test project targets `net8.0`.

## Architecture

The renderer is intentionally split into a small number of layers:

- `HtmlRenderer` builds a display list from the AngleSharp render tree and computed styles.
- `DisplayList` is the backend-agnostic command model.
- `SkiaRenderBackend` turns the display list into a PNG using SkiaSharp.
- `HtmlRenderOptions` holds viewport and text defaults.
- `AngleSharp.Css` provides the render tree and computed-style data used by the renderer.

Current behavior includes block layout, margins, padding, borders, floats, inline-block, relative/fixed/absolute positioning, z-index ordering, outlines, text styling, text alignment, line-height, letter-spacing, text-indent, vertical-align, and generic font-family handling.

## Code Conventions

Follow the repository's existing C# style, which is defined by `.editorconfig` and the existing source files:

- 4 spaces for code files, 2 spaces for `.csproj` files.
- LF line endings and UTF-8.
- Trim trailing whitespace.
- Use `var` where the type is obvious from the right-hand side.
- Keep changes narrow and consistent with nearby code.
- Preserve the existing file style instead of reformatting whole files.

## Tests And Snapshots

Tests are split between structural assertions and visual conformance checks.

- Structural tests live in `src/AngleSharp.Renderer.Tests/HtmlRendererTests.cs` and verify the display list directly.
- Visual tests live in `src/AngleSharp.Renderer.Tests/VisualConformanceTests.cs` and compare PNG output against baselines in `verification-assets/`.
- Failed visual comparisons write the actual image and a diff image into `failure-assets/`.
- Missing baselines are auto-created unless `ANGLESHARP_SNAPSHOT_STRICT=1` or `true` is set.
- CI runs visual tests on both Linux and Windows. To reduce drift, the renderer uses bundled deterministic font files for generic font-family resolution.

When changing renderer behavior, update or add tests first, then run the focused test file or the full test project.

## Repository Notes

- The docs live under `docs/general/` and `docs/tutorials/`; they are the best place to document user-facing renderer behavior.
- `AGENTS.md` should remain the primary agent note for this repo.
- The repository already carries a snapshot-based workflow, so visual changes usually require updating the baseline PNGs together with the code change.
- The Linux Skia setup uses native assets from the main project package references.
- Keep an eye on `failure-assets/` after test runs; they are useful diagnostics, not source of truth.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# 0.2.0

Released on Friday, July 31 2026.

- Added more drawing modes such as tables, floats, ...
- Added `WithRendering` extension to register rendering service

# 0.1.0

Released on ?.
Released on Tuesday, July 28 2026.

- Initial release
8 changes: 8 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

The guidance is shared with every AI agent working here, so it lives in AGENTS.md and is
imported below. Record new guidance there rather than in this file.

@AGENTS.md
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ The project now contains a first draft implementation with:
- A backend-agnostic rendering core and display-list model
- A SkiaSharp backend that renders PNG output
- A basic DOM-driven text layout pass (block flow, heading scaling, word wrapping)
- Basic support for HTML canvas via a bitmap-backed 2D rendering context

This is an initial vertical slice and not a full browser-grade layout engine yet.

Expand All @@ -26,7 +27,7 @@ This is an initial vertical slice and not a full browser-grade layout engine yet
using AngleSharp;
using AngleSharp.Renderer;

var context = BrowsingContext.New(Configuration.Default);
var context = BrowsingContext.New(Configuration.Default.WithCss().WithRendering());
var document = await context.OpenAsync(req => req.Content(@"
<html>
<body>
Expand All @@ -45,6 +46,8 @@ var image = renderer.RenderToPng(document, new HtmlRenderOptions
await File.WriteAllBytesAsync("render.png", image.Data);
```

Registering the rendering service with `WithRendering()` is also what enables support for `<canvas>` elements and their 2D drawing context. The renderer currently provides a lightweight bitmap-backed implementation for common drawing operations such as rectangles, paths, text, clear operations, and simple state management.

## Design Direction

The current architecture is intentionally split into two layers:
Expand All @@ -60,4 +63,4 @@ This project is supported by the [.NET Foundation](https://dotnetfoundation.org)

## License

AngleSharp.Css is released using the MIT license. For more information see the [license file](./LICENSE).
AngleSharp.Renderer is released using the MIT license. For more information see the [license file](./LICENSE).
Loading
Loading