A Swift library implementing CoreGraphics-compatible APIs and WebGPU rendering for WebAssembly (WASM) environments.
OpenCoreGraphics enables cross-platform Swift code to use a broad CoreGraphics-compatible surface where Apple's framework is unavailable. Compatibility remains a target contract and is validated per API and rendering path.
| Evidence | Result |
|---|---|
| Native package | 977 tests passed |
| Browser | 10 real-browser tests passed through WebGPU readback, including fills, image masks, callback patterns, HDR tone mapping, image rendering, and cap/join/dash stroke geometry |
| Color management | Named RGB/gray/HDR, calibrated RGB/gray, and ICC matrix/TRC, LUT, and floating-point multi-process profiles convert through D50 XYZ or Lab PCS; graphics-state rendering intents reach solid, gradient, shading, pattern, image, and shadow rendering without silent source-color fallback. Device-dependent and profiled spaces with the same color model preserve their finite component contract when no shared profile transform exists, while incompatible ICC endpoints still fail explicitly. Immutable CGColor and CGColorSpace use checked Sendable conformance |
| Font outlines and metrics | Static and gvar-variable TrueType glyf, OpenType CFF1/Type2, and CFF2 variable outlines execute through the normal CGContext path; gvar tuple decoding, IUP interpolation, composite placement, phantom-point metrics, and shared ItemVariationStore HVAR/VVAR processing are active. Skia variable bounds and advances plus CFF1/CFF2 conformance are checked against Apple CoreText/CoreGraphics |
| PostScript fonts | PFA and PFB Type 1 fonts load through encrypted eexec/CharStrings parsing with Subrs, Flex, seac, metrics, names, and FontMatrix normalization. Type 1 subsets are generated from TrueType, CFF1, and CFF2 outlines; Type 42 produces a physically subsetted, checksum-correct TrueType SFNT. Generated and reloaded fonts are validated by Apple CoreGraphics/CoreText |
| Path normalization | Winding and even-odd normalization resolves overlapping contours into filled boundaries; connected-component separation keeps holes with their direct outer contour and emits filled islands independently. Nested-contour behavior is checked against Apple Core Graphics |
| Path geometry | Tight Bézier bounds, containment, dashing, transforms, caps, joins, miter limits, and adaptive stroke outlines are checked against Apple Core Graphics; software and WebGPU renderers consume the same stroke geometry |
| Bitmap compositing | The software bitmap renderer uses nested transparency backing stores, applies group opacity once, implements every Porter-Duff operator, and renders axial/radial gradients with current alpha, blend mode, clipping, and destination color conversion. Every selected backend is stored through the stateful renderer contract, so release-WASM cannot discard clip or graphics state through a failed runtime protocol cast. WebGPU gradients consume the same graphics-state alpha and blend contract |
| Scope boundary | PDF parsing, writing, and rendering are intentionally outside the project scope |
Add OpenCoreGraphics to your Package.swift:
dependencies: [
.package(url: "https://github.com/1amageek/OpenCoreGraphics.git", from: "1.0.0")
]Then add it to your target:
.target(
name: "YourTarget",
dependencies: ["OpenCoreGraphics"]
)Use conditional imports to support both Apple platforms and WASM:
#if canImport(CoreGraphics)
import CoreGraphics
#else
import OpenCoreGraphics
#endif// Create a bitmap context
let context = CGContext(
data: nil,
width: 400,
height: 300,
bitsPerComponent: 8,
bytesPerRow: 400 * 4,
space: CGColorSpace(name: CGColorSpace.sRGB)!,
bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)
)!
// Draw shapes
context.setFillColor(CGColor(red: 1, green: 0, blue: 0, alpha: 1))
context.fill(CGRect(x: 50, y: 50, width: 100, height: 80))
context.setStrokeColor(CGColor(red: 0, green: 0, blue: 1, alpha: 1))
context.setLineWidth(3)
context.strokeEllipse(in: CGRect(x: 200, y: 50, width: 100, height: 100))
// Get the rendered image
let image = context.makeImage()let path = CGMutablePath()
path.move(to: CGPoint(x: 100, y: 100))
path.addLine(to: CGPoint(x: 200, y: 100))
path.addLine(to: CGPoint(x: 150, y: 200))
path.closeSubpath()
context.addPath(path)
context.setFillColor(.red)
context.fillPath()let gradient = CGGradient(
colorSpace: CGColorSpace(name: CGColorSpace.sRGB)!,
colors: [CGColor.red, CGColor.blue],
locations: [0, 1]
)!
context.drawLinearGradient(
gradient,
start: CGPoint(x: 0, y: 0),
end: CGPoint(x: 400, y: 300),
options: []
)context.saveGState()
context.translateBy(x: 200, y: 150)
context.rotate(by: .pi / 4)
context.scaleBy(x: 2, y: 2)
context.fill(CGRect(x: -25, y: -25, width: 50, height: 50))
context.restoreGState()On WASM, OpenCoreGraphics uses WebGPU for hardware-accelerated rendering. Call setupGraphicsContext() once at application startup to initialize WebGPU.
import OpenCoreGraphics
@main
struct MyApp {
static func main() async throws {
// Initialize WebGPU (call once at startup)
try await setupGraphicsContext()
// Now use CGContext normally
let context = CGContext(
data: nil,
width: 400,
height: 300,
bitsPerComponent: 8,
bytesPerRow: 400 * 4,
space: CGColorSpace(name: CGColorSpace.sRGB)!,
bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)
)!
context.setFillColor(CGColor(red: 1, green: 0, blue: 0, alpha: 1))
context.fill(CGRect(x: 0, y: 0, width: 100, height: 100))
// GPU readback
let image = await context.makeImageAsync()
}
}setupGraphicsContext() throws GraphicsContextError if initialization fails:
do {
try await setupGraphicsContext()
} catch GraphicsContextError.webGPUNotSupported {
// Browser doesn't support WebGPU
} catch GraphicsContextError.adapterNotAvailable {
// Failed to get WebGPU adapter
} catch GraphicsContextError.deviceNotAvailable {
// Failed to get WebGPU device
}WebGPU is required for WASM rendering. Supported browsers:
- Chrome 113+
- Edge 113+
- Firefox 139+ (with flags)
- Safari 18+ (macOS Sequoia / iOS 18)
CGFloat,CGPoint,CGSize,CGRect,CGVectorCGAffineTransform,CGAffineTransformComponents
CGContext,CGImage,CGPath,CGMutablePath,CGLayer
CGColor,CGColorSpace,CGColorSpaceModel,CGColorConversionInfoCGComponent,CGBitmapInfo,CGImageAlphaInfo
CGGradient,CGShading,CGPattern,CGFunction
CGDataProvider,CGDataConsumer
CGPDFDocument,CGPDFPage,CGPDFObject,CGPDFScannerare present for source compatibility, but parser, writer, and renderer paths are not implemented and do not advertise success.
CGFont
CGBlendMode,CGTextDrawingMode,CGInterpolationQualityCGGradientDrawingOptions,CGPathFillRule,CGLineCap,CGLineJoin- And more...
# Build the package
swift build
# Run focused tests with a 30-second process timeout
perl -e 'alarm 30; exec @ARGV' -- \
xcodebuild test -scheme OpenCoreGraphics -destination 'platform=macOS' \
-only-testing:OpenCoreGraphicsTests
# Build for WASM (requires Swift SDK for WASM)
TOOLCHAINS=org.swift.64202607171a xcrun swift build \
--swift-sdk swift-6.4.x-DEVELOPMENT-SNAPSHOT-2026-07-17-a_wasm
# Run the real-browser WebGPU suite
cd Tests/e2e && npm test# Install the Swift WASM SDK
swift sdk install https://github.com/aspect-build/aspect-wasm32-wasi-release/releases/latest/download/swift-wasm32-wasi.artifactbundle.zip
# List installed SDKs
swift sdk list- Swift
swift-6.4.x-DEVELOPMENT-SNAPSHOT-2026-07-17-a - For WASM builds: Swift WASM SDK
This library is designed with WASM compatibility as a primary goal. All implementations use pure Swift types that work seamlessly in WebAssembly environments.
OpenCoreGraphics is built entirely with Swift standard types:
Stringfor names and identifiersDatafor binary data[String: Any]for property lists and dictionariesUIntfor type identifiers
All standard color space names are available as String constants:
CGColorSpace.sRGB // "kCGColorSpaceSRGB"
CGColorSpace.displayP3 // "kCGColorSpaceDisplayP3"
CGColorSpace.genericGrayGamma2_2 // "kCGColorSpaceGenericGrayGamma2_2"
CGColorSpace.genericCMYK // "kCGColorSpaceGenericCMYK"
// ... and many moreNamed RGB/gray/HDR and calibrated spaces convert through a D50 profile connection space. HLG uses the BT.2100 inverse OETF and luminance-coupled OOTF with the 203-nit extended-linear reference. ICC v2/v4 profiles support matrix/TRC, mft1, mft2, mAB, mBA, and floating-point D2B/B2D multi-process transforms. The mpet executor supports segmented curve sets, arbitrary channel matrices, multidimensional float CLUTs, bACS/eACS pass-through elements, direct absolute-colorimetric transforms, XYZ/Lab PCS, rendering-intent overrides, CICP HDR metadata, and CMYK/DeviceN profiles. Invalid known elements and channel contracts are rejected; unknown future elements use the ICC-defined integer-table fallback.
- Full API Compatibility: Identical type names, method signatures, and property names as CoreGraphics
- WASM First: Uses pure Swift types that work in WebAssembly environments
- Same Behavior: Consistent semantics with Apple's implementation
- Modern Swift: All value types are
@frozenand conform toSendable,Hashable,Equatable, andCodable - No Deprecated APIs: Only current, non-deprecated CoreGraphics APIs are implemented
- Performance Optimized: Uses
@inlinablefor performance-critical methods
All geometric value types (CGFloat, CGPoint, CGSize, CGRect, CGVector, CGAffineTransform) conform to:
Sendable- Thread-safeHashable- Can be used in Sets and as Dictionary keysEquatable- Equality comparisonCodable- JSON serialization support
Additionally, CGFloat conforms to all numeric protocols:
FloatingPoint,BinaryFloatingPointSignedNumeric,NumericComparable,Strideable
MIT License