{"id":23684498,"url":"https://github.com/antouhou/grafo","last_synced_at":"2026-05-19T01:01:52.532Z","repository":{"id":269872150,"uuid":"809702755","full_name":"antouhou/grafo","owner":"antouhou","description":"GPU-accelerated rendering library for Rust","archived":false,"fork":false,"pushed_at":"2026-02-22T22:35:51.000Z","size":7642,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-22T23:36:16.126Z","etag":null,"topics":["graphics","gui","renderer","text-rendering","vector-graphics"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/antouhou.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-06-03T09:34:38.000Z","updated_at":"2026-02-22T21:52:13.000Z","dependencies_parsed_at":"2024-12-26T20:18:27.972Z","dependency_job_id":"3a14955f-9aa9-43e9-91ae-971cde7379a5","html_url":"https://github.com/antouhou/grafo","commit_stats":null,"previous_names":["antouhou/grafo"],"tags_count":22,"template":false,"template_full_name":null,"purl":"pkg:github/antouhou/grafo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antouhou%2Fgrafo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antouhou%2Fgrafo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antouhou%2Fgrafo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antouhou%2Fgrafo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/antouhou","download_url":"https://codeload.github.com/antouhou/grafo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antouhou%2Fgrafo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29951101,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-28T18:42:55.706Z","status":"ssl_error","status_checked_at":"2026-02-28T18:42:48.811Z","response_time":90,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["graphics","gui","renderer","text-rendering","vector-graphics"],"created_at":"2024-12-29T20:45:54.586Z","updated_at":"2026-05-19T01:01:52.516Z","avatar_url":"https://github.com/antouhou.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Grafo\n\n[![Grafo crate](https://img.shields.io/crates/v/grafo.svg)](https://crates.io/crates/grafo)\n[![Grafo documentation](https://docs.rs/grafo/badge.svg)](https://docs.rs/grafo)\n[![Build and test](https://github.com/antouhou/grafo/actions/workflows/rust.yml/badge.svg?branch=main)](https://github.com/antouhou/grafo/actions)\n\nGrafo is a GPU-accelerated rendering library for Rust. It’s a quick way to render shapes and images, with masking and hierarchical clipping built in.\n\nThe library is designed for flexibility and ease of use, making it suitable for a wide \nrange of applications, from simple graphical interfaces to complex rendering engines.\n\n## Features\n\n* Shape Rendering: Create and render vector shapes (with optional texture layers).\n* (Text rendering was previously integrated; it has now been extracted into a separate crate - https://crates.io/crates/protextinator)\n* Stencil Operations: Advanced stencil operations for clipping and masking.\n* Shape hierarchy: Attach shapes to parent nodes and choose whether each parent clips descendants.\n* Per-instance data: Set transform and color per shape instance (no fill color stored on geometry).\n* Antialiasing: You can choose between built-in support of inflated geometry or MSAA\n\nGrafo is [available on crates.io](https://crates.io/crates/grafo), and\n[API Documentation is available on docs.rs](https://docs.rs/grafo/).\n\n## Getting Started\n\nAdd the following to your `Cargo.toml`:\n\n```toml\n[dependencies]\ngrafo = \"0.10\"\nwinit = \"0.30\"      # For window creation and event handling\nimage = \"0.25\"      # For image decoding (textures)\nenv_logger = \"0.11\" # For logging\nlog = \"0.4\"         # For logging\n```\n\n### Basic Usage\n\nBelow is a minimal snippet showing how to create a shape, set per-instance color and transform, and render. For a complete runnable window using `winit` 0.30 (ApplicationHandler API), see `examples/basic.rs`.\n\n```rust\nuse grafo::{Color, Shape, ShapeDrawCommandOptions, Stroke};\n\n// Create a rectangle shape (no fill color on the shape itself)\nlet rect = Shape::rect(\n    [(0.0, 0.0), (200.0, 100.0)],\n    Stroke::new(2.0, Color::BLACK),\n);\nrenderer\n    .add_shape(\n        rect,\n        None,\n        None,\n        ShapeDrawCommandOptions::new()\n            .color(Color::rgb(0, 128, 255))\n            .transform(grafo::TransformInstance::translation(100.0, 100.0)),\n    )\n    .unwrap();\n\n// Render one frame (typical winit loop would call this on RedrawRequested)\nrenderer.render().unwrap();\nrenderer.clear_draw_queue();\n```\n\n### Shape hierarchy and overflow\n\nThe second argument to `add_shape` and `add_clipping_rect` is the optional\n`parent_shape_id`. A child is drawn inside that parent in the draw tree.\nBy default, children are clipped to their parent:\n\n```rust\nuse grafo::{Color, Shape, ShapeDrawCommandOptions, Stroke};\n\nlet clipping_parent_id = renderer\n    .add_shape(\n        Shape::rect([(0.0, 0.0), (120.0, 80.0)], Stroke::default()),\n        None,\n        None,\n        ShapeDrawCommandOptions::new().color(Color::rgb(220, 220, 220)),\n    )\n    .unwrap();\n\nrenderer\n    .add_shape(\n        Shape::rect([(80.0, 20.0), (160.0, 60.0)], Stroke::default()),\n        Some(clipping_parent_id),\n        None,\n        ShapeDrawCommandOptions::new().color(Color::rgb(220, 80, 80)),\n    )\n    .unwrap();\n\n// Let children render outside `overflow_parent_id`, while still respecting any ancestor clip.\nlet overflow_parent_id = renderer\n    .add_shape(\n        Shape::rect([(0.0, 0.0), (120.0, 80.0)], Stroke::default()),\n        None,\n        None,\n        ShapeDrawCommandOptions::new()\n            .color(Color::rgb(220, 220, 220))\n            .clips_children(false),\n    )\n    .unwrap();\n\nrenderer\n    .add_shape(\n        Shape::rect([(80.0, 20.0), (160.0, 60.0)], Stroke::default()),\n        Some(overflow_parent_id),\n        None,\n        ShapeDrawCommandOptions::new().color(Color::rgb(220, 80, 80)),\n    )\n    .unwrap();\n\n// The same call works for ids returned by `add_clipping_rect`, so clip rectangles\n// can also be used as non-clipping containers.\n```\n\n## Examples\n\n- `basic.rs` – draw simple shapes (winit 0.30 ApplicationHandler)\n- `transforms.rs` – demonstrates per-instance transform and color, perspective, and hit-testing\n\nFor a detailed example showcasing advanced features like hierarchical clipping and\nmulti-layer shape texturing, please refer to the \n[examples](https://github.com/antouhou/grafo/tree/main/examples) directory in the repository.\n\n### Multi-texturing (Background + Foreground)\n\nShapes support up to two texture layers that are composited with per-instance color using premultiplied alpha:\n\n1. Background layer (index 0 / `TextureLayer::Background`)\n2. Foreground layer (index 1 / `TextureLayer::Foreground`)\n\nComposition order (bottom to top):\n\n`final = foreground + (background + color * (1 - background.a)) * (1 - foreground.a)`\n\nAPI:\n\n```rust\nuse grafo::{Color, Renderer, Shape, ShapeDrawCommandOptions, Stroke};\n\n// After allocating textures via renderer.texture_manager()\nrenderer\n    .add_shape(\n        Shape::rect([(0.0, 0.0), (300.0, 200.0)], Stroke::new(1.0, Color::BLACK)),\n        None,\n        None,\n        ShapeDrawCommandOptions::new()\n            .color(Color::rgb(40, 40, 40))\n            .background_texture_id(bg_tex_id)\n            .foreground_texture_id(fg_tex_id),\n    )\n    .unwrap();\n\n// Single-layer helper (Background):\nrenderer\n    .add_shape(\n        Shape::rect([(0.0, 0.0), (300.0, 200.0)], Stroke::new(1.0, Color::BLACK)),\n        None,\n        None,\n        ShapeDrawCommandOptions::new()\n            .color(Color::WHITE)\n            .background_texture_id(bg_tex_id),\n    )\n    .unwrap(); // useful when texture transparency should reveal white\n```\n\nSee `examples/multi_texture.rs` for a runnable demo that generates procedural background \u0026 foreground textures.\n\n### Positioning shapes\n\nUse per-shape transforms to position shapes. Common helpers:\n\n- Translate: `TransformInstance::translation(tx, ty)`\n- Scale: `TransformInstance::scale(sx, sy)`\n- Rotate (Z): `TransformInstance::rotation_z_deg(deg)`\n- Compose: `a.multiply(\u0026b)` (or `a.then(\u0026b)`) applies `a` first, then `b`\n\nExample:\n\n```rust\nuse grafo::ShapeDrawCommandOptions;\n\nlet r = grafo::TransformInstance::rotation_z_deg(15.0);\nlet t = grafo::TransformInstance::translation(150.0, 80.0);\n// Rotate first, then translate\nrenderer\n    .add_shape(\n        my_shape,\n        None,\n        None,\n        ShapeDrawCommandOptions::new().transform(r.then(\u0026t)),\n    )\n    .unwrap();\n```\n\n## Documentation\n\n[Documentation is available on docs.rs](https://docs.rs/grafo/).\n- [Renderer architecture notes](./docs/renderer-architecture.md)\n\n## Contributing\n\nEveryone is welcome to contribute in any way or form! For further details, please read [CONTRIBUTING.md](./CONTRIBUTING.md).\n\n## Authors\n- [Anton Suprunchuk](https://github.com/antouhou) - [Website](https://antouhou.com)\n\nAlso, see the list of contributors who participated in this project.\n\n## License\n\nThis project is licensed under the MIT License - see the\n[LICENSE.md](./LICENSE.md) file for details\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantouhou%2Fgrafo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fantouhou%2Fgrafo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantouhou%2Fgrafo/lists"}