Skip to content

Implement flair-ui: complete Vulkan-backed 2D vector graphics library in Zig#1

Draft
Copilot wants to merge 6 commits intomasterfrom
copilot/implement-2d-vector-graphics-library
Draft

Implement flair-ui: complete Vulkan-backed 2D vector graphics library in Zig#1
Copilot wants to merge 6 commits intomasterfrom
copilot/implement-2d-vector-graphics-library

Conversation

Copy link
Copy Markdown

Copilot AI commented Apr 15, 2026

  • Explore codebase and understand all files needing changes
  • Create src/c_headers/vulkan.h wrapper header
  • Create src/c_headers/wayland.h wrapper header
  • Update build.zig — add b.addTranslateC() steps for both headers and wire modules into the library
  • Update src/vulkan.zig — replace @cImport with @import("vulkan_c")
  • Update src/platform/wayland.zig — replace @cImport with @import("wayland_c")
  • Update src/image.zig — replace removed std.compress.zlib with a manual DEFLATE-stored / zlib encoder
  • Update build.zig.zon — bump minimum_zig_version to "0.16.0"
Original prompt

Overview

Implement a complete 2D vector graphics library in Zig that depends exclusively on Vulkan for rendering. The library is called flair-ui and should provide a clean, ergonomic public API.

Core Concepts

1. Surface — The Central Drawing Primitive

A Surface is the primary thing users draw onto. It is backed by a Vulkan image/framebuffer.

  • A surface has a width, height, and pixel format (RGBA8).
  • All drawing operations target a surface.
  • A surface can be saved to disk as an image (PNG format — use a pure-Zig PNG encoder or a minimal stb_image_write binding).
  • A surface can be presented to a window (see below).

2. Drawing Primitives / Shapes

The library must support drawing the following shapes. Every shape can be drawn as either filled or as stroked (outline) with a configurable stroke width:

  1. Line — from point A to point B, with configurable width.
  2. Path — a sequence of connected line segments (polyline). Can be open or closed.
  3. Bézier curves — quadratic and cubic Bézier curves, defined by control points.
  4. Circle — defined by center + radius.
  5. Circular arc — a portion of a circle, defined by center, radius, start angle, end angle.
  6. Oval (Ellipse) — defined by center + x-radius + y-radius.
  7. Oval arc (Elliptical arc) — a portion of an ellipse.
  8. Rectangle — defined by position + size, with an optional corner radius for each corner independently (to support rounded rects, pill shapes, etc.).

3. Color & Paint System

  • Colors are RGBA (f32 components, 0.0–1.0).
  • A Paint type represents how a shape is filled/stroked:
    • Solid color
    • Linear gradient — defined by two points + array of color stops
    • Radial gradient — defined by center, radius + array of color stops
  • Paint is passed as a parameter to every draw call.

4. Draw Style

Every shape draw function accepts a DrawStyle:

  • .fill — fill the interior
  • .stroke with a configurable line_width

5. Window — Platform-Agnostic Abstraction

A Window presents a surface to the screen and handles input.

  • The Window interface/API must be platform-agnostic so it can later be ported to macOS (Metal/Cocoa) and Windows (Win32).
  • Use a vtable or tagged-union pattern in Zig for the platform backend.
  • For now, implement only the Wayland backend:
    • Use libwayland-client via Zig's @cImport / C interop.
    • Use xdg-shell for window decoration/toplevel.
    • Present the Vulkan surface to the Wayland surface via VK_KHR_wayland_surface.
  • The window should support:
    • Creating/destroying a window with a title and size.
    • Resizing.
    • Closing.
    • An event loop (pollEvents() or similar).

6. Input Handling

The window must handle user input and expose it through an event system:

  • Keyboard events: key press, key release, key repeat. Include the key code/scancode and modifier state (shift, ctrl, alt, super).
  • Mouse events:
    • Mouse button press/release (left, right, middle, etc.)
    • Mouse move (position)
    • Mouse scroll (vertical and horizontal)
    • Mouse enter/leave the window
  • Events should be delivered through a polling model: the user calls something like window.pollEvents() which returns an iterator/slice of events, or the user registers callback functions.
  • For Wayland, keyboard input comes from wl_keyboard and mouse from wl_pointer via the wl_seat interface.

Architecture & File Structure

flair-ui/
├── build.zig                  # Build script: compile shaders (GLSL→SPIR-V), link Vulkan, link wayland
├── build.zig.zon              # Package manifest
├── src/
│   ├── root.zig               # Public API — re-exports everything users need
│   ├── surface.zig            # Surface type, create/destroy, save-to-image
│   ├── renderer.zig           # Vulkan initialization, pipeline management, draw command submission
│   ├── vulkan.zig             # Vulkan helpers: instance, device, swapchain, memory, etc.
│   ├── shapes.zig             # Shape tessellation: convert shapes → triangle vertices on CPU
│   ├── color.zig              # Color, Gradient, ColorStop, Paint types
│   ├── image.zig              # PNG encoding / image export
│   ├── window.zig             # Platform-agnostic Window interface (vtable pattern)
│   ├── input.zig              # Event types: KeyEvent, MouseButtonEvent, MouseMoveEvent, ScrollEvent
│   ├── platform/
│   │   └── wayland.zig        # Wayland backend: wl_display, xdg_shell, wl_seat, wl_keyboard, wl_pointer
│   └── shaders/
│       ├── fill.vert.glsl     # Vertex shader — passes position + UV + color to fragment
│       └── fill.frag.glsl     # Fragment shader — handles solid color and gradient interpolation
├── examples/
│   ├── basic_shapes.zig       # Example: draw all shape types to a surface, save as PNG
│   └── window_events.zig      # Example: open a window, draw shapes, handle mouse/keyboard
└── README.md                  # Documenta...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

*This pull request was created from Copilot chat.*
>

Copilot AI and others added 3 commits April 15, 2026 17:19
Agent-Logs-Url: https://github.com/YesserLab/flair-ui/sessions/71b406ca-a075-4223-a055-51b24b574e1e

Co-authored-by: YesserLab <2708404+YesserLab@users.noreply.github.com>
…iling whitespace

Agent-Logs-Url: https://github.com/YesserLab/flair-ui/sessions/71b406ca-a075-4223-a055-51b24b574e1e

Co-authored-by: YesserLab <2708404+YesserLab@users.noreply.github.com>
Copilot AI changed the title [WIP] Add 2D vector graphics library using Vulkan Implement flair-ui: complete Vulkan-backed 2D vector graphics library in Zig Apr 15, 2026
Copilot AI requested a review from YesserLab April 15, 2026 17:48
- Replace @cImport (deprecated in 0.16) with b.addTranslateC() for
  both the Vulkan and Wayland C headers.  Two wrapper headers are added
  under src/c_headers/ and two named modules (vulkan_c, wayland_c) are
  wired into lib.root_module in build.zig.
- Replace removed std.compress.zlib.compressor in image.zig with a
  hand-rolled zlibStoreCompress() that writes a valid RFC 1950 zlib
  stream using RFC 1951 DEFLATE stored blocks.
- Bump minimum_zig_version in build.zig.zon to "0.16.0".

Agent-Logs-Url: https://github.com/YesserLab/flair-ui/sessions/e03440a2-8ed1-44e3-8fc0-f260407bd3b2

Co-authored-by: YesserLab <2708404+YesserLab@users.noreply.github.com>
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.

2 participants