.agents/skills/api-add-review/references/add-workflow.md
Step-by-step workflow for adding new C# APIs to SkiaSharp by wrapping Skia C++ functionality. After completing all phases, the review-workflow runs automatically to verify the API meets design standards.
Read api-design-rules.md before starting — it defines naming, Span patterns, property conventions, and test requirements.
main or skiasharp branch — Check with git branchgit checkout -b dev/issue-NNNN-descriptioncd externals/skia && git checkout -b dev/issue-NNNN-descriptionFind the C++ API in Skia headers and identify:
SkFourByteTag or similar typedefs that need wrapping[inout] vs return value semanticsexternals/skia/include/c/sk_*.h with SK_C_APIexternals/skia/src/c/sk_*.cppAsType()/ToType() conversion macros from sk_types_priv.hsk_ref_sp().release()For layout-compatible C/C++ structs (same field types and order):
// In sk_types_priv.h — generates As*/To* via reinterpret_cast
#include "include/c/sk_typeface.h"
DEF_MAP(SkFontArguments::VariationPosition::Coordinate,
sk_fontarguments_variation_position_coordinate_t,
VariationPositionCoordinate)
// In sk_structs.cpp — compile-time size check
static_assert(sizeof(sk_fontarguments_variation_position_coordinate_t) ==
sizeof(SkFontArguments::VariationPosition::Coordinate),
ASSERT_MSG(SkFontArguments::VariationPosition::Coordinate,
sk_fontarguments_variation_position_coordinate_t));
For non-layout-compatible structs (e.g., isHidden() getter vs bool field):
// Manual converter
static inline sk_fontarguments_variation_axis_t ToVariationAxis(
const SkFontParameters::Variation::Axis& axis) {
return { axis.tag, axis.min, axis.def, axis.max, axis.isHidden() };
}
For parameter bag helpers:
static inline SkFontArguments AsSkFontArguments(
const sk_fontarguments_variation_position_coordinate_t* coordinates,
int coordinateCount, int collectionIndex) {
SkFontArguments args;
args.setCollectionIndex(collectionIndex);
args.setVariationDesignPosition(
{AsVariationPositionCoordinate(coordinates), coordinateCount});
return args;
}
For uint32_t-based types like tags:
typedef uint32_t sk_fourbytetag_t;
Then map in libSkiaSharp.json:
"sk_fourbytetag_t": { "cs": "SKFourByteTag" }
cd externals/skia && git commit)git add externals/skia)git status shows "modified: externals/skia (new commits)"pwsh ./utils/generate.ps1SkiaApi.generated.cs contains new function*.generated.cs fileIf HarfBuzz headers changed, ensure the correct version is checked out for generation (may differ from build version — check DEPS).
Apply the rules from api-design-rules.md:
Since you added/modified C API functions, you MUST rebuild:
# macOS (Apple Silicon)
dotnet cake --target=externals-macos --arch=arm64
# If GN is killed (error 137), re-sign: codesign --force --sign - externals/skia/bin/gn
Follow the test requirements from api-design-rules.md:
dotnet test tests/SkiaSharp.Tests.Console/SkiaSharp.Tests.Console.csproj
Tests MUST PASS. Do not skip, do not claim completion if they fail.
Every user-facing API should be demonstrated in the Gallery sample app. Decide whether the feature needs a new sample or should enhance an existing one:
| Feature scope | Action | Example |
|---|---|---|
| Standalone capability (new drawing mode, new input type, new rendering technique) | Create new sample file | VariableFontSample.cs, ColorFontSample.cs |
| Enhancement to existing capability (new overload, new option, extra parameter) | Update existing sample | Adding optical size slider to an existing font sample |
| Internal/plumbing API (no visible user effect) | No sample needed | ABI-only struct changes |
samples/Gallery/Shared/Samples/{FeatureName}Sample.csCanvasSampleBase (for drawing) or DocumentSampleBase (for PDF/XPS)Title, Description, and Category (use SampleCategories.* constants)SampleMedia (add embedded resources to Media/ if needed)SampleMedia.cs if you added assetsusing or override OnDestroy)static readonly arrays for fixed values (weights, etc.)using for per-frame objects, OnDestroy for cached objectssamples/Gallery/Shared/
├── Controls/SampleControl.cs # SliderControl, PickerControl, ToggleControl, GroupControl
├── SampleBase.cs # Base: Title, Description, Category, Controls
├── CanvasSampleBase.cs # OnDrawSample(canvas, width, height), IsAnimated
├── DocumentSampleBase.cs # For PDF/XPS document output
├── SampleCategories.cs # Category constants
├── SampleMedia.cs # Embedded resource loader (Images, Fonts)
├── Media/ # Embedded assets (fonts, images, JSON)
└── Samples/ # One file per sample
Run the review-workflow.md against your changes. Fix any issues it identifies. Re-run tests after fixes.