Skip to content

iOS port, expanded SVG filter pipeline, WebKit PSNR test harness#15

Open
duncanwilcox wants to merge 1 commit into
IconJar:masterfrom
duncanwilcox:feat/ios-svg-filters-psnr-tests
Open

iOS port, expanded SVG filter pipeline, WebKit PSNR test harness#15
duncanwilcox wants to merge 1 commit into
IconJar:masterfrom
duncanwilcox:feat/ios-svg-filters-psnr-tests

Conversation

@duncanwilcox
Copy link
Copy Markdown

This consolidates ~55 patches accumulated against IJSVG in Sitely's tree since 2024. The themes:

iOS / iPadOS port

  • New IJSVGPlatform.{h,m} centralizes macOS/iOS differences: AppKit/UIKit imports, NSColor/NSImage/NSView/NSFont/NSBezierPath shims, geometry typedefs and macros, an NSValue (IJSVGGeometry) category bridging NS-named methods to their CG-named iOS counterparts, and a UIView (IJSVGNeedsDisplay) category exposing a BOOL-taking -setNeedsDisplay: shim.
  • New IJSVGiOSXML.{h,m} provides a libxml2-backed NSXMLNode/Element/Document replacement for iOS (Foundation on iOS doesn't ship NSXML*).
  • Existing headers migrated from direct <AppKit/AppKit.h> + <Foundation/Foundation.h> imports to <IJSVG/IJSVGPlatform.h>.

SVG filter pipeline (biggest body of work)

  • Filter graph + 7 filter effects on top of the existing IJSVGFilterEffectGaussianBlur: Blend, ColorMatrix, Composite, DisplacementMap, Flood, Lighting, Merge, Offset, Turbulence; plus IJSVGFilterGraph orchestrating the pipeline with CALayer → bitmap replacement rendering.
  • filterUnits parsing and filter region attributes honored so SVGs with missing attributes no longer trigger huge-bitmap allocations.
  • feOffset rendering fixed; filter export round-trip works.
  • Filter rasterization respects the root viewBox transform.
  • Filter layer CGImage lifetime made safe across redraws.
  • Filter region stabilized at 10% with vImage edge extension.
  • Filter-before-opacity rendering: source graphic rendered at full opacity (+26 dB on the gradient-filter baseline).
  • Blur calibration matching WebKit (CIGaussianBlur with padded source bitmap, after experimenting with a vImage 3-pass box blur path).
  • Turbulence Y-flip corrected.

Gradients / patterns / masks

  • spreadMethod="reflect" implemented for linear gradients (+15.8 dB on the car baseline).
  • Gradient mask rendering works (masks with gradient content).
  • SVG viewport, gradient, and pattern regressions resolved.
  • Pattern image transform handling improved.
  • Clip-path transform propagation fixed.
  • Imported upstream gradient-stop-parsing fixes.

Color space

  • All deviceRGB references converted to sRGB throughout the framework.
  • rgb() colors use sRGB (+9 dB on the tommek car baseline).

Parser robustness

  • Forward-reference prescan so <use> inside <clipPath> can target elements defined later in the document.
  • Realloc bug fixed for SVGs with more than 5 transforms.
  • NaN/Inf attribute workarounds in gradient parsing.
  • IJSVGParser crash on certain SVGs ("circled-arrow-left.svg") fixed.
  • IJSVGExporter crashes fixed.

CoreAnimation / memory / stability

  • Background-thread CATransaction crash patched.
  • Numerous memory leaks fixed.
  • @available guards added for APIs not available in 10.14.4 / iOS 17.
  • All in-framework logging removed.

Test harness (in IJSVGExample)

  • New IJSVGWebKitPSNRTests.m: renders an SVG with IJSVG and snapshots the same SVG in a WKWebView, writes IJSVG/WebKit/diff PNGs and a PSNR results log. Overridable via IJSVG_OUTPUT_DIR and IJSVG_WEBKIT_SETTLE_DELAY env vars.
  • IJSVGExampleTests converted to a standalone (logic) test bundle: TEST_HOST/BUNDLE_LOADER removed, IJSVG.framework linked directly and embedded in the .xctest bundle, SVG resources bundled in the test target, scheme promoted from xcuserdata to xcshareddata.
  • WebKit.framework linked into the test target.

This consolidates ~55 patches accumulated in Sitely's tree since 2024.
The themes:

iOS / iPadOS port
- New IJSVGPlatform.{h,m} centralizes macOS/iOS differences: AppKit/UIKit
  imports, NSColor/Image/View/Font/BezierPath shims, geometry typedefs
  and macros, NSValue (IJSVGGeometry) category bridging NS-named methods
  to their CG-named iOS counterparts, and a UIView (IJSVGNeedsDisplay)
  category exposing a BOOL-taking -setNeedsDisplay: shim.
- New IJSVGiOSXML.{h,m} provides a libxml2-backed
  NSXMLNode/Element/Document replacement for iOS (Foundation on iOS
  doesn't ship NSXML*).
- Existing headers migrated from direct <AppKit/AppKit.h> +
  <Foundation/Foundation.h> imports to <IJSVG/IJSVGPlatform.h>.
- Sitely.h indirection removed from framework headers; NSGraphicsGetCurrentContext
  is provided by IJSVGPlatform (inline on macOS, UIGraphicsGetCurrentContext
  on iOS).

SVG filter pipeline (biggest body of work)
- Filter graph + 7 filter effects on top of the existing
  IJSVGFilterEffectGaussianBlur: IJSVGFilterEffectBlend, ColorMatrix,
  Composite, DisplacementMap, Flood, Lighting, Merge, Offset, Turbulence;
  plus IJSVGFilterGraph orchestrating the pipeline with CALayer→bitmap
  replacement rendering.
- filterUnits parsing and filter region attributes honored so SVGs
  with missing attributes no longer trigger huge-bitmap allocations.
- feOffset rendering fixed; filter export round-trip works.
- Filter rasterization respects the root viewBox transform.
- Filter layer CGImage lifetime made safe across redraws.
- Filter region stabilized at 10% with vImage edge extension.
- Filter-before-opacity rendering: source graphic rendered at full
  opacity (+26 dB on the gradient-filter baseline).
- Blur calibration matching WebKit (CIGaussianBlur with padded source
  bitmap, after experimenting with a vImage 3-pass box blur path).
- Turbulence Y-flip corrected.

Gradients / patterns / masks
- spreadMethod="reflect" implemented for linear gradients
  (+15.8 dB on the car baseline).
- Gradient mask rendering works (masks with gradient content).
- SVG viewport, gradient, and pattern regressions resolved.
- Pattern image transform handling improved.
- Clip-path transform propagation fixed.
- Imported upstream gradient-stop-parsing fixes.

Color space
- All deviceRGB references converted to sRGB throughout the framework.
- rgb() colors use sRGB (+9 dB on the tommek car baseline).

Parser robustness
- Forward-reference prescan so <use> inside <clipPath> can target
  elements defined later in the document.
- Realloc bug fixed for SVGs with more than 5 transforms.
- NaN/Inf attribute workarounds in gradient parsing.
- IJSVGParser crash on certain SVGs ("circled-arrow-left.svg") fixed.
- IJSVGExporter crashes fixed.

CoreAnimation / memory / stability
- Background-thread CATransaction crash patched.
- Numerous memory leaks fixed.
- @available guards added for APIs not available in 10.14.4 / iOS 17.
- All in-framework logging removed.

Test harness (in IJSVGExample)
- New IJSVGWebKitPSNRTests.m: renders an SVG with IJSVG and snapshots
  the same SVG in a WKWebView, writes IJSVG/WebKit/diff PNGs and a
  PSNR results log. Overridable via IJSVG_OUTPUT_DIR and
  IJSVG_WEBKIT_SETTLE_DELAY env vars.
- IJSVGExampleTests converted to a standalone (logic) test bundle:
  TEST_HOST/BUNDLE_LOADER removed, IJSVG.framework linked directly and
  embedded in the .xctest bundle, SVG resources bundled in the test
  target, scheme promoted from xcuserdata to xcshareddata.
- WebKit.framework linked into the test target.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant