Skip to content

Releases: MriyaLab/Pysar

v0.1.63

Choose a tag to compare

@kolodiichyk kolodiichyk released this 01 Oct 07:08

Avalonia fonts

Report fonts can come from Avalonia FontManager.
UsePysar installs a typeface fallback before your configuration. The family string in the report must be the Avalonia FontFamily string — fonts:Inter#Inter after WithInterFont, or avares://MyApp/Fonts#Ubuntu for a resource folder — not a file path. A bare name is a system-font lookup; if TryGetGlyphTypeface substitutes Helvetica, Pysar treats that as a miss.

AddFont still wins. A library ReportAsset still needs one AddFont: the file is not copied into the head, and FontManager does not see it. A XAML FontFamily resource is not a registration. Styles stay Normal, Bold, Italic and BoldItalic. This bridge is Avalonia only. Console, the design-time preview, MAUI, WPF and Uno keep AddFont.

PDF export

PDF/A-2b is an option of PDF, not another format.
Pass new PdfExportOptions { PdfA = true } to SavePdfAsync, RenderToPdfAsync, RenderToPdfBytesAsync, or IReportExportService.ExportAsync. Skia writes the archival document setup: XMP pdfaid identification, a document UUID, and an sRGB output intent. It does not validate the file. A font Skia cannot embed still fails a checker, and the UUID makes those bytes non-reproducible. Existing overloads are unchanged.

Images

SVG is drawn from the bytes, not only from a .svg path.
A stream or embedded source whose bytes start with <svg (optional XML declaration) is rendered as SVG. A decode or parse failure is recorded on the image cache, so the same bad bytes are not decoded again. Fixes #23.

Rendering

A built report may be rendered more than once, only sequentially.
PDF and then page bitmaps, or a retry of the same export, is supported. Do not render one instance concurrently. PageNumber and PageCount are scratch written during the pass, and OnPageChanged runs again on every render.

Uno

Android report pages no longer depend on OpenGL ES.
UsePysar sets UseOpenGLOnSkiaAndroid to false before the window is created. OpenGL ES draws image textures as opaque black, which hid every report page.

Internal

  • Host startup (Avalonia, MAUI, WPF, Uno) shares one installation sequence, PysarInstallation.
  • InternalsVisibleTo for Pysar.Avalonia and Pysar.Avalonia.Tests.

Full changelog: v0.1.56...HEAD

v0.1.56

Choose a tag to compare

@kolodiichyk kolodiichyk released this 20 Sep 18:51

Zoom & gestures

Trackpad wheel events are now aggregated into a single gesture.
Wheel events are timestamped and grouped using a new WheelGestureGap, and the wheel
anchor in ReportView is kept persistent for the duration of the gesture instead of
being recomputed per event.

Sub-threshold pinch frames are deferred.
GestureModel.PinchByStep / PinchByScale now report whether the change actually
reached the ZoomModel. Small frames are accumulated and only written once they exceed
ZoomStepThreshold. This fixes the visual drift between the model zoom and the rendered
pages during slow pinches.

Added tests covering the accumulation behaviour and confirming that presenter and page
layout do not drift across many sub-threshold frames.

Internal

  • InternalsVisibleTo added for the WPF test assembly, enabling direct unit tests of
    internal Pysar.Wpf logic without widening the public API.

Full changelog: v0.1.53...HEAD

v0.1.53

Choose a tag to compare

@kolodiichyk kolodiichyk released this 20 Sep 07:58

Highlights

ReportAsset — a single way to ship report assets

Fonts, images and other report resources can now be declared once as a
ReportAsset MSBuild item. The build translates it into each host framework's
own item type (MauiAsset, AvaloniaResource, EmbeddedResource, …), and a new
EmbeddedAssetFileSystem reads assets straight from the manifest resources of
assemblies marked with [PysarAssetSource]. This means a shared report library
can carry its own fonts and images, and every host can see them.

A new FallbackFileSystem chains the platform's own asset source ahead of the
embedded one. All five UI platforms (MAUI, WPF, Avalonia, Uno, Blazor) and both
disk-backed DefaultReportPlatformHandler constructors install this chain, so
console apps, workers, server-side rendering and the design-time preview resolve
embedded assets too.

An IFileSystem you pass explicitly is not widened — it stays the caller's
whole answer.

Trimming support

Pysar.dll now embeds an ILLink.Descriptors.xml, and Pysar.Xaml ships a
build/Pysar.Xaml.targets that auto-generates an embedded trimmer descriptor for
any project containing .rxaml reports (opt out with PysarDisableTrimmerRoots).
See docs/trimming.md for WebAssembly trimming behaviour.

Avalonia: shared renderer and export

New PysarAvalonia entry point with a shared renderer/export service and proper
reset logic behind AppBuilderExtensions, plus headless Avalonia tests.

Platform layer refactor

Platform-specific handlers are replaced by DefaultReportPlatformHandler backed
by per-platform IFileSystem implementations. Desktop/macOS printing and the
macOS pinch monitor moved into Pysar.Viewer.Platform, and desktop print logic is
centralised in DesktopPdfPrint. Obsolete platform shims were removed.

Performance

  • ImageRenderCache — a session-scoped cache for image bytes, bitmaps and
    SVGs, wired into both the prefetch and draw paths, with failure tracking and
    deterministic disposal.
  • Faster layout — GridLayoutMeasurer, StackLayoutMeasurer, TextMeasurer
    and LayoutEngine were reworked; BindingEngine and PropertyPathResolver
    were optimised.
  • Removed the #if DEBUG [Pysar.Perf] zoom instrumentation that logged to the
    console in every consumer's Debug build.

Fixes

  • Stale pinch-zoom tiles — rapid pinch commits could leave superseded zoom
    generations in the tile cache, keeping cells from older scales on screen. Only
    the active generation and one bridge generation are kept now.
  • Touch axis lock — ReportView locks a swipe to its dominant axis, so
    scrolling no longer drifts sideways.
  • WPF printing — the printer now imports the viewer platform namespace it
    needs for the print flow.

Authoring and tooling

  • XAML source generation: richer binding validation with namespace/name
    collection and real diagnostics.
  • New API surface: StyleExtensions.WithStyle, AddElements overloads on
    ReportContainer, PysarBuilder.AddFonts, and a default Band height.
  • Quick start and the MAUI/Uno/Avalonia READMEs now document ReportAsset
    instead of hand-declared asset items.

Breaking changes

  • MeasureAsync / ProbeAsync are now synchronous Measure / Probe
    throughout the layout and rendering pipeline. Custom element measurers and any
    code calling the measure API must drop await and the Task return type.
  • Platform handler types removed — MauiReportPlatformHandler,
    WpfReportPlatformHandler and AvaloniaReportPlatformHandler are gone; use
    DefaultReportPlatformHandler (installed for you by UsePysar /
    AddPysar / UsePysar() on the app builder).
  • IImageCache / LocalImageCache lost members superseded by ImageRenderCache.
  • PysarWpf and Pysar.Avalonia.ReportView helper shims were removed.

Tests

~2,000 lines of new test coverage: embedded-asset and fallback file systems,
per-platform asset chains, pinch-commit placement, image-render caching, PDF
print on desktop, trimmer roots and package layout, and binding validation.

v0.1.46

Choose a tag to compare

@kolodiichyk kolodiichyk released this 18 Sep 04:48

Changed

  • Lowered the Uno.WinUI floor from 6.7.103 to 6.6.184. Pysar.Uno previously
    demanded a version no app on Uno.Sdk 6.6.42 could satisfy — the Sdk supplies
    6.6.184 itself, making the higher floor a hard resolution failure rather than a
    warning. Pysar.Uno uses no API newer than 6.6, so the floor now matches.
  • This is a floor, not a ceiling: consumers on Uno.Sdk 6.7.30 still resolve
    6.7.135, and the Uno sample builds against 6.8.0-dev.159 from its own Sdk.
  • HarfBuzzSharp remains at 14.2.1.1 — only its outdated rationale comment was
    corrected, since Svg.Skia (14.2.0), not Uno, is what drives that version now.

Notes

  • Apps blocked on Uno.WinUI 6.7.103 can now stay on Uno 6.6 — or move to
    Uno.Sdk 6.7.30, which is published as stable.

v0.1.44

Choose a tag to compare

@kolodiichyk kolodiichyk released this 16 Sep 05:50

Highlights

Content assets under Assets/

Packaged Uno Content lives under Assets/. Report code still asks for Fonts/, Images/, and Styles/. UsePysarAsync preloads ms-appx:///Assets/... at startup so later reads stay synchronous.

Report sharing

PysarUno.Sharer (UnoReportSharer) offers exported bytes to the host: a file download on WebAssembly, and open/share on desktop, Android, and iOS.

var pdf = await PysarUno.ExportService.ExportAsync(builtReport, ExportFormat.Pdf);
await PysarUno.Sharer.ShareAsync(pdf, "report.pdf");

v0.1.41

Choose a tag to compare

@kolodiichyk kolodiichyk released this 15 Sep 17:43

Highlights

Uno integration: a real entry point

Registering Pysar in an Uno application is now a single call on Application, and it works the same
way from every head (WebAssembly, Desktop, Android, iOS, WinAppSDK) — OnLaunched is the one place
they all run through.

protected override void OnLaunched(LaunchActivatedEventArgs args)
{
    this.UsePysar(typeof(App).Assembly, pysar => pysar
        .AddFont("Fonts/Ubuntu-Regular.ttf", "Ubuntu")
        .AddFont("Fonts/Ubuntu-Bold.ttf", "Ubuntu", FontStyle.Bold));
}
  • ApplicationExtensions.UsePysar(...) and UsePysarAsync(...) — the latter preloads
    ms-appx:/// assets for applications that ship them as Content rather than EmbeddedResource.
  • assetAssembly is required: on the WebAssembly head the entry assembly is the head project, not
    the application project the assets are packaged into.
  • Registration moved into UnoRegistration; PysarUno now exposes PlatformHandler /
    ExportService and resets the export service on re-registration.

Ctrl+wheel and trackpad pinch zoom the report, not the page (browser head)

ReportView has always zoomed on Ctrl+wheel and marked the event handled, but on a browser head
that changed nothing visible: "handled" is a managed routing flag, while page zoom is a DOM default
action that only preventDefault on a non-passive listener stops. The reader got a scaled page and
a report that never moved — and the trackpad pinch went with it, since Chrome and Safari deliver it
as a wheel event with ctrlKey set.

UsePysar now installs a small embedded script, imported from a data URL, so a consuming
application adds one call and no files. Opt out with suppressBrowserZoom: false to keep the
browser's own zoom as an accessibility affordance.

Suppression covers the whole Uno canvas: Uno draws the entire application into a single canvas, so
the DOM cannot tell the report from the toolbar beside it. Anything on the page outside that canvas
keeps the browser's zoom.

Measure probe caching

New MeasureContext and LayoutEngine.ProbeSizeAsync cache probe measurements, and
GridLayoutMeasurer / StackLayoutMeasurer now measure through probes instead of re-measuring the
same subtree repeatedly — a large drop in repeat measures on nested layouts.

A readable diagnostic for the SkiaSharp native/managed split on WebAssembly

An Uno browser head pulls SkiaSharp.NativeAssets.WebAssembly through
Uno.WinUI.Runtime.Skia.WebAssembly.Browser, which asks for the 3.119 line, while Pysar renders
through 4.151. NuGet resolves one managed SkiaSharp and one native archive, and the two no longer
agree.

Every other platform reports that split as a startup exception with a message of its own.
WebAssembly links the native side statically at build time, so it surfaces instead as a wall of
wasm-ld: undefined symbol: sk_* lines naming entry points the application never wrote, with
nothing pointing at the version that caused them.

The check now ships as buildTransitive, so it reaches consumers who referenced Pysar.Uno or
Pysar.Blazor rather than Pysar itself — those are the ones who end up on a browser head.
Declaring a dependency on the native package would fix it silently, but it is a 67 MB download
charged to every WPF, console and Uno desktop consumer that will never link a wasm binary.

Breaking changes

  • PysarUno.Use(...) and PysarUno.UseAsync(...) are removed. Use Application.UsePysar(...) /
    UsePysarAsync(...) instead.

Other

  • Docs updated: root README.md, src/Pysar.Uno/README.md, docs/quick-start.md.
  • New AGENTS.md; added opencode.json.
  • Tests: UnoRegistrationTests, MeasureProbeCachingTests, and a new PackageLayoutTests
    assertion for the buildTransitive payload.

Full Changelog: v0.1.38...v0.1.42

v0.1.38

Choose a tag to compare

@kolodiichyk kolodiichyk released this 14 Sep 20:13

Added

  • Pysar.Uno: a new platform package for Uno Platform. One net10.0 target covers every Uno Skia host - Desktop, WebAssembly, Android and iOS - and it brings the same ReportView the other platform packages do: a scrollable, zoomable viewer that rasterises only the visible region, so memory follows the viewport rather than the zoom level. Built against Uno 6.7.
  • PysarUno.Use(assembly, configure) / PysarUno.UseAsync(...) (Pysar.Uno): registration for an Uno application, called from OnLaunched. A static entry point rather than a service registration, because an Uno application has no service collection of its own unless it also uses Uno.Extensions. Returns the handler, and exposes the shared PysarUno.Renderer and PysarUno.ExportService.
  • UnoReportPlatformHandler and UnoAssetFileSystem (Pysar.Uno): report assets are read from embedded resources whose LogicalName is the path the report asks for. Embedded rather than ms-appx:/// because font registration, ResourceDictionary sources and image loading all read synchronously, and blocking on Uno's asynchronous StorageFile deadlocks the single-threaded WebAssembly host. UnoAssetFileSystem.PreloadAsync fetches Content-packaged assets once at startup for applications that would rather keep them that way.
  • UnoReportPrinter (Pysar.Uno): desktop printing through the same vector PDF pipeline as export - the macOS Print panel via PDFKit, the shell print verb on Windows, the default viewer on Linux. Android, iOS and WebAssembly throw PlatformNotSupportedException; produce the bytes through PysarUno.ExportService and share or download them from the application.
  • MacPinchMonitor and MacMagnifyEventArgs (Pysar.Core.Platform, in Pysar): an AppKit local event monitor for NSEventTypeMagnify, now public and shared by every host that needs it. No user-interface framework tested surfaces a trackpad pinch as a gesture on macOS - it arrives as plain wheel deltas indistinguishable from a two-finger scroll - so a trackpad zoom has to come from AppKit directly. Start/Stop are no-ops on every other platform.

Changed

  • MacPinchMonitor moved from Pysar.Avalonia, where it was internal, into Pysar. Behaviour is unchanged for Avalonia applications; the type is simply no longer duplicated per host. It is plain P/Invoke against libobjc with no dependency on any user-interface framework, which is why it belongs beside MacOsPdfPrint in the core package.
  • HarfBuzzSharp moves from 14.2.0 to 14.2.1.1 across every package, managed wrapper and native assets together. Required by Uno, and applied as a family because a split between the managed wrapper and its native assets is a startup crash rather than a build error.
  • Docs: the quick start and README now cover Uno alongside the other platforms, including the two places it deviates - registration is PysarUno.Use rather than UsePysar/AddPysar, and assets are embedded resources rather than package URIs.

Notes

  • Pysar.Uno 0.1.35-preview, published earlier to the internal feed, is superseded and should not be used. It required an Uno.WinUI prerelease that no released Uno.Sdk provides, so no standard Uno application could consume it. This release targets stable Uno 6.7 instead and ships as an ordinary stable package.
  • The Uno report view has been exercised on macOS Desktop - loading, pagination, zoom modes, and trackpad pinch. Its other hosts (WebAssembly, Android, iOS) build from the same single target but have not yet been run.

v0.1.34

Choose a tag to compare

@kolodiichyk kolodiichyk released this 13 Sep 13:17

Added

  • DefaultReportPlatformHandler (Pysar.Skia): a ready-made IReportPlatformHandler for hosts without a UI framework - console and worker applications, server-side rendering, and the design-time preview. Pass a directory to its constructor when assets do not sit next to the binaries.
  • LocalFileSystem (Pysar.Skia): an IFileSystem/ISyncFileSystem that reads report assets from disk. Relative paths resolve against the application's deployment directory, rooted paths are read as given, and a missing asset reads as null instead of throwing.

Fixed

  • Asset paths now resolve against AppContext.BaseDirectory rather than the executing binary, so images and fonts are found when the assembly is loaded by a host such as dotnet app.dll or the design-time preview.

Changed

  • Rounded-border rendering builds its ring path with SKPathBuilder, matching the current SkiaSharp path API.
  • Docs: quick start and README now describe DefaultReportPlatformHandler as the default, with the UI-framework handlers (AvaloniaReportPlatformHandler, WpfReportPlatformHandler, MauiReportPlatformHandler, WasmPlatformHandler) registered by UsePysar/AddPysar.

v0.1.31

Choose a tag to compare

@kolodiichyk kolodiichyk released this 11 Sep 19:37

Added

  • Report watermarks: Report.Watermark / ReportBuilder.WithWatermark, XAML child, repeats on every page, full physical page, Layer (behind or in front of content), IsVisible.
  • Opacity (0..1) and visual Rotation (around bounds center) on report elements.
  • Rounded frames: CornerRadius (1 or 4 values). Borders wrap the inner content radius; children clip to the inner arc.
  • XAML file overlay for unsaved editor buffers during preview/resource load (overlay wins over disk).

Fixed

  • MAUI pinch/zoom after Shell flyout navigation (stale recognizers on the old scroll view).
  • ReportView gesture lifecycle: detach/reattach on handler changes and Loaded, so gestures survive navigation.

Changed

  • Native libraries: SkiaSharp 4.151.2, Svg.Skia 5.2.3, HarfBuzzSharp + native assets, MAUI / Microsoft.Extensions 10.x.

0.1.24

Choose a tag to compare

@kolodiichyk kolodiichyk released this 06 Sep 14:30

Fixed

  • Print dialogs now use the report’s page size and orientation (Blazor, MAUI, macOS), including landscape and Android media size.
  • Blank report after navigation (e.g. Shell flyout): session is recreated when the tile cache was disposed.
  • MAUI share on iOS / Mac Catalyst no longer crashes after a successful share.
  • Local XAML values (e.g. FontFamily) are no longer overwritten by implicit styles; styles and bindings now follow value precedence.

Improved

  • Faster, smoother scrolling/zoom: tile pooling, coalesced redraws, per-page tile cache, less work per frame.
  • Each NuGet package now ships its own README.

Notes

  • Sample apps were removed from this repo.