Skip to content

Implement missing Microsoft.Maui.Graphics platform support#12

Merged
Redth merged 4 commits intomainfrom
feature/graphics-implementation
Mar 27, 2026
Merged

Implement missing Microsoft.Maui.Graphics platform support#12
Redth merged 4 commits intomainfrom
feature/graphics-implementation

Conversation

@Redth
Copy link
Copy Markdown
Owner

@Redth Redth commented Mar 5, 2026

Summary

Addresses #11 — implements the missing platform layer for the GTK4 backend.

What changed

New files:

  • Graphics/CairoCanvas.cs — Full ICanvas implementation backed by Cairo + PangoCairo text layout
  • Graphics/CairoPlatformImage.csIImage implementation backed by Cairo.ImageSurface
  • Graphics/CairoGraphicsServices.cs — Platform services: IStringSizeService, IBitmapExportService, IImageLoadingService
  • Pages/GraphicsFeaturePage.cs — Comprehensive demo page exercising all graphics features (10 sections)

Modified:

  • Handlers/GraphicsViewHandler.cs — Uses extracted CairoCanvas; adds interaction events
  • Hosting/AppHostBuilderExtensions.cs — Registers graphics platform services

Phase 1 — Core drawing fixes

  • Path operations: all PathOperation segment types (Move, Line, Cubic, Quad→Cubic, Arc, Close)
  • Stroke properties: dash patterns, line caps, line joins, miter limit
  • Text measurement via Pango layout (GetPixelSize)
  • Gradient paints (linear and radial via Cairo P/Invoke)
  • Text alignment (horizontal + vertical) and font weight/style

Phase 2 — Missing canvas operations

  • ConcatenateTransform (Matrix3x2 → Cairo matrix)
  • DrawImage + CairoPlatformImage
  • Antialias and BlendMode applied to Cairo context
  • SubtractFromClip (even-odd fill rule technique)
  • Interaction events (GestureClick, GestureDrag, EventControllerMotion)

Phase 3 — Platform services and effects

  • Shadow rendering (multi-pass offset blur)
  • IStringSizeService (Pango-based text measurement)
  • IBitmapExportService (Cairo ImageSurface + PNG export)
  • IImageLoadingService (PNG loading via CairoPlatformImage)

Phase 4 — Pango text layout

  • Replace Cairo toy text API with PangoCairo layout for all text rendering
  • Multi-line word wrapping via Pango.Layout.SetWidth/SetWrap
  • lineSpacingAdjustment via Pango.Layout.SetSpacing
  • IAttributedText support via PangoAttrList (bold, italic, underline, strikethrough, color, font size)
  • Pango-based text measurement in CairoStringSizeService

Still TODO (future PRs)

  • True Gaussian blur shadow rendering via Cairo surface compositing

Redth and others added 4 commits March 5, 2026 15:41
Phase 1 - Fix core drawing correctness:
- Rewrite DrawPathInternal to handle all PathOperation segment types
  (Move, Line, Cubic bezier, Quad bezier, Arc, Close) using
  PathF.GetSegmentType/GetPointsForSegment API
- Apply stroke properties (dash patterns, line caps/joins, miter limit)
  to Cairo context in ApplyStroke()
- Replace fake GetStringSize (length*fontSize*0.6) with proper Cairo
  TextExtents/FontExtents measurement
- Implement gradient paint support (LinearGradientPaint, RadialGradientPaint)
  via cairo_pattern_create_linear/radial P/Invoke
- Implement text alignment (horizontal/vertical) and font weight/style
  in DrawString using text/font extents for positioning

Phase 2 - Complete missing canvas operations:
- Implement ConcatenateTransform via Cairo.Matrix.Init + cr.Transform
- Implement DrawImage with CairoPlatformImage (IImage backed by
  Cairo.ImageSurface) including Downsize, Resize, Save, FromStream
- Apply Antialias and BlendMode properties to Cairo context
- Implement SubtractFromClip via even-odd fill rule trick
- Store SetShadow parameters (rendering deferred to future work)

Phase 3 - GraphicsView interaction events:
- Wire GestureClick for StartInteraction/EndInteraction/CancelInteraction
- Wire GestureDrag for DragInteraction
- Wire EventControllerMotion for hover events

Architecture:
- Extract CairoCanvas from GraphicsViewHandler.cs to dedicated
  Graphics/CairoCanvas.cs file (grew from ~280 to ~660 lines)
- Add Graphics/CairoPlatformImage.cs implementing IImage + IDrawable

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Phase 3 - Platform services:
- CairoStringSizeService (IStringSizeService): Text measurement using
  temporary Cairo surface + TextExtents/FontExtents
- CairoBitmapExportService (IBitmapExportService): Creates
  CairoBitmapExportContext backed by Cairo ImageSurface with ICanvas
  and IImage properties, plus WriteToStream via PNG export
- CairoImageLoadingService (IImageLoadingService): Loads images from
  streams via CairoPlatformImage.FromStream

All three registered as singletons in AppHostBuilderExtensions.cs.

Shadow rendering:
- SetShadow now stores offset/blur/color and DrawShadowFill renders
  offset copies with decreasing alpha to approximate blur for fill
  operations (FillRectangle, FillRoundedRectangle, FillEllipse, FillPath)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds a comprehensive demo page to the sample app with 9 IDrawable
sections that exercise every graphics feature implemented for issue #11:

1. Path operations: cubic bezier, quadratic bezier, arc, closed paths
2. Stroke properties: dash patterns, line caps (butt/round/square),
   line joins (miter/round/bevel)
3. Gradient paint: linear gradient, radial gradient, gradient on path
4. Text features: horizontal/vertical alignment, font weight/style,
   GetStringSize measurement
5. ConcatenateTransform: rotation, scale, skew, composite transforms
6. Shadow rendering: shadows on rect, rounded rect, ellipse, path
7. Antialias & BlendMode: aliased vs antialiased, Xor and DestOver
8. SubtractFromClip: ClipRectangle, SubtractFromClip, ClipPath
9. Interaction events: StartInteraction, EndInteraction, DragInteraction,
   hover events with live log display

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Upgrades all text rendering in CairoCanvas from Cairo's toy font API
(ShowText/TextExtents/SelectFontFace) to PangoCairo layout:

Text rendering:
- DrawString uses Pango.Layout with word wrapping via SetWidth/SetWrap
- Horizontal alignment via Pango.Alignment (Left/Center/Right)
- Vertical alignment computed from GetPixelSize (Top/Center/Bottom)
- lineSpacingAdjustment applied via SetSpacing
- Font weight/style via Pango.FontDescription (SetWeight/SetStyle)
- TextFlow.ClipBounds clips to bounding rectangle

Text measurement:
- GetStringSize uses Pango.Layout.GetPixelSize for accurate sizing
- CairoStringSizeService updated to use PangoCairo instead of Cairo

IAttributedText support:
- DrawText builds PangoAttrList from IAttributedTextRun attributes
- Supports Bold, Italic, Underline, Strikethrough, FontSize, Color
- Correct UTF-8 byte index conversion for attribute ranges

Sample app:
- Added section 10 (Multi-line Text Wrapping) to GraphicsFeaturePage
- Shows wrapped text with Left/Top, Center/Center, Right/Bottom alignment

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Redth Redth merged commit af24e0b into main Mar 27, 2026
2 checks passed
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