{"id":13423586,"url":"https://github.com/sammycage/lunasvg","last_synced_at":"2025-07-27T10:19:09.706Z","repository":{"id":36963603,"uuid":"249957284","full_name":"sammycage/lunasvg","owner":"sammycage","description":"SVG rendering and manipulation library in C++","archived":false,"fork":false,"pushed_at":"2025-03-06T19:47:56.000Z","size":1732,"stargazers_count":963,"open_issues_count":2,"forks_count":135,"subscribers_count":28,"default_branch":"master","last_synced_at":"2025-03-06T20:30:32.905Z","etag":null,"topics":["cpp","css","plutovg","png","svg","svg2png"],"latest_commit_sha":null,"homepage":"","language":"C++","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/sammycage.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","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},"funding":{"buy_me_a_coffee":"sammycage","custom":["https://www.paypal.me/sammycage"]}},"created_at":"2020-03-25T11:13:00.000Z","updated_at":"2025-03-06T19:48:01.000Z","dependencies_parsed_at":"2023-01-17T09:01:05.086Z","dependency_job_id":"949ea619-84cf-43b1-b238-ca6740bb082f","html_url":"https://github.com/sammycage/lunasvg","commit_stats":null,"previous_names":[],"tags_count":31,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sammycage%2Flunasvg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sammycage%2Flunasvg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sammycage%2Flunasvg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sammycage%2Flunasvg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sammycage","download_url":"https://codeload.github.com/sammycage/lunasvg/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243766969,"owners_count":20344847,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["cpp","css","plutovg","png","svg","svg2png"],"created_at":"2024-07-31T00:00:38.218Z","updated_at":"2025-07-27T10:19:09.699Z","avatar_url":"https://github.com/sammycage.png","language":"C++","funding_links":["https://buymeacoffee.com/sammycage","https://www.paypal.me/sammycage"],"categories":["C++","Graphics"],"sub_categories":[],"readme":"[![Actions](https://github.com/sammycage/lunasvg/actions/workflows/main.yml/badge.svg)](https://github.com/sammycage/lunasvg/actions)\n[![License](https://img.shields.io/github/license/sammycage/lunasvg)](https://github.com/sammycage/lunasvg/blob/master/LICENSE)\n[![Releases](https://img.shields.io/github/v/release/sammycage/lunasvg)](https://github.com/sammycage/lunasvg/releases)\n[![Donate](https://img.shields.io/badge/Donate-PayPal-blue.svg)](https://www.paypal.me/sammycage)\n\n\u003e Interested in HTML rendering? Explore a related library, [PlutoBook](https://github.com/plutoprint/plutobook), built for paged HTML rendering.\n\n# LunaSVG\n\nLunaSVG is an SVG rendering library in C++, designed to be lightweight and portable, offering efficient rendering and manipulation of Scalable Vector Graphics (SVG) files.\n\n## Basic Usage\n\n```cpp\n#include \u003clunasvg.h\u003e\n\nusing namespace lunasvg;\n\nint main()\n{\n    auto document = Document::loadFromFile(\"tiger.svg\");\n    if(document == nullptr)\n        return -1;\n    auto bitmap = document-\u003erenderToBitmap();\n    if(bitmap.isNull())\n        return -1;\n    bitmap.writeToPng(\"tiger.png\");\n    return 0;\n}\n\n```\n\n![tiger.png](https://github.com/user-attachments/assets/b87bbf92-6dd1-4b29-a890-99cfffce66b8)\n\n---\n\n## Dynamic Styling\n\n```cpp\n#include \u003clunasvg.h\u003e\n\nusing namespace lunasvg;\n\nstatic const char kLandspaceContent[] = R\"SVG(\n\u003csvg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 800 600\" width=\"800\" height=\"600\"\u003e\n  \u003c!-- Background (Sky) --\u003e\n  \u003crect width=\"800\" height=\"600\" class=\"sky\"/\u003e\n\n  \u003c!-- Sun --\u003e\n  \u003ccircle cx=\"650\" cy=\"150\" r=\"80\" class=\"sun\" /\u003e\n\n  \u003c!-- Clouds --\u003e\n  \u003cellipse cx=\"200\" cy=\"150\" rx=\"100\" ry=\"40\" class=\"cloud\" /\u003e\n  \u003cellipse cx=\"250\" cy=\"200\" rx=\"120\" ry=\"50\" class=\"cloud\" /\u003e\n  \u003cellipse cx=\"500\" cy=\"80\" rx=\"150\" ry=\"60\" class=\"cloud\" /\u003e\n  \u003cellipse cx=\"550\" cy=\"120\" rx=\"120\" ry=\"50\" class=\"cloud\" /\u003e\n\n  \u003c!-- Mountains --\u003e\n  \u003cpolygon points=\"0,450 200,200 400,450\" class=\"mountain\" /\u003e\n  \u003cpolygon points=\"200,450 400,100 600,450\" class=\"mountain\" /\u003e\n  \u003cpolygon points=\"400,450 600,250 800,450\" class=\"mountain\" /\u003e\n\n  \u003c!-- Foreground (Ground) --\u003e\n  \u003crect y=\"450\" width=\"800\" height=\"150\" class=\"ground\" /\u003e\n\u003c/svg\u003e\n)SVG\";\n\nstatic const char kSummerStyle[] = R\"CSS(\n.sky { fill: #4A90E2; }\n.sun { fill: #FF7F00; }\n.mountain { fill: #2E3A59; }\n.cloud { fill: #FFFFFF; opacity: 0.8; }\n.ground { fill: #2E8B57; }\n)CSS\";\n\nstatic const char kWinterStyle[] = R\"CSS(\n.sky { fill: #87CEEB; }\n.sun { fill: #ADD8E6; }\n.mountain { fill: #2F4F4F; }\n.cloud { fill: #FFFFFF; opacity: 0.8; }\n.ground { fill: #FFFAFA; }\n)CSS\";\n\nint main()\n{\n    auto document = Document::loadFromData(kLandspaceContent);\n\n    document-\u003eapplyStyleSheet(kSummerStyle);\n    document-\u003erenderToBitmap().writeToPng(\"summer.png\");\n\n    document-\u003eapplyStyleSheet(kWinterStyle);\n    document-\u003erenderToBitmap().writeToPng(\"winter.png\");\n    return 0;\n}\n```\n\n| `summer.png` | `winter.png` |\n| --- | --- |\n| ![summer.png](https://github.com/user-attachments/assets/c7f16780-23f8-4acd-906a-2242f2d0d33b) | ![winter.png](https://github.com/user-attachments/assets/fdd65288-11c7-4e16-bb5a-2bf28de57145) |\n\n---\n\n## Hit Testing\n\nThis example demonstrates SVG element hit testing using `elementFromPoint(x, y)` in LunaSVG. It loads an SVG containing three shapes, performs point-based hit detection, and applies a skew transform with a black stroke to each matched element. The results are saved as `original.png` and `modified.png` for visual comparison.\n\n```cpp\n#include \u003clunasvg.h\u003e\n\n#include \u003cutility\u003e\n#include \u003ciostream\u003e\n\nusing namespace lunasvg;\n\nstatic const char kSVGContent[] = R\"SVG(\n\u003csvg width=\"400\" height=\"200\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\n  \u003crect id=\"red-rect\" x=\"20\" y=\"20\" width=\"100\" height=\"100\" fill=\"red\"/\u003e\n  \u003ccircle id=\"blue-circle\" cx=\"200\" cy=\"70\" r=\"50\" fill=\"blue\"/\u003e\n  \u003crect id=\"green-rect\" x=\"300\" y=\"30\" width=\"70\" height=\"130\" fill=\"green\"/\u003e\n\u003c/svg\u003e\n)SVG\";\n\nint main()\n{\n    auto document = Document::loadFromData(kSVGContent);\n\n    document-\u003erenderToBitmap().writeToPng(\"original.png\");\n\n    const std::pair\u003cfloat, float\u003e points[] = {\n        {30,  30}, // inside red-rect\n        {200, 70}, // center of blue-circle\n        {310, 50}, // inside green-rect\n        {0,    0}, // outside all shapes\n    };\n\n    for(const auto\u0026 [x, y] : points) {\n        if(auto element = document-\u003eelementFromPoint(x, y)) {\n            std::cout \u003c\u003c \"Element at (\" \u003c\u003c x \u003c\u003c \", \" \u003c\u003c y \u003c\u003c \"): \" \u003c\u003c element.getAttribute(\"id\") \u003c\u003c \"\\n\";\n\n            element.setAttribute(\"stroke\", \"black\");\n            element.setAttribute(\"stroke-width\", \"3\");\n            element.setAttribute(\"transform\", \"skewX(9)\");\n        } else {\n            std::cout \u003c\u003c \"No element found at (\" \u003c\u003c x \u003c\u003c \", \" \u003c\u003c y \u003c\u003c \")\\n\";\n        }\n    }\n\n    document-\u003erenderToBitmap().writeToPng(\"modified.png\");\n    return 0;\n}\n```\n\n| `original.png` | `modified.png` |\n| --- | --- |\n| ![original.png](https://github.com/user-attachments/assets/bbffbd84-6311-484b-bfe3-219d7aec055b) | ![modified.png](https://github.com/user-attachments/assets/a7f6e502-a64f-48d5-8a01-901ad15b108b) |\n\n```log\nElement at (30, 30): red-rect\nElement at (200, 70): blue-circle\nElement at (310, 50): green-rect\nNo element found at (0, 0)\n```\n\n## Features\n\nLunaSVG supports nearly all graphical features outlined in the SVG 1.1 and SVG 1.2 Tiny specifications. The primary exceptions are animation, filters, and scripts. As LunaSVG is designed for static rendering, animation is unlikely to be supported in the future. However, support for filters may be added. It currently handles a wide variety of elements, including:\n\n`\u003ca\u003e` `\u003ccircle\u003e` `\u003cclipPath\u003e` `\u003cdefs\u003e` `\u003cellipse\u003e` `\u003cg\u003e` `\u003cimage\u003e` `\u003cline\u003e` `\u003clinearGradient\u003e` `\u003cmarker\u003e` `\u003cmask\u003e` `\u003cpath\u003e` `\u003cpattern\u003e` `\u003cpolygon\u003e` `\u003cpolyline\u003e` `\u003cradialGradient\u003e` `\u003crect\u003e` `\u003cstop\u003e` `\u003cstyle\u003e` `\u003csvg\u003e` `\u003csymbol\u003e` `\u003ctext\u003e` `\u003ctspan\u003e` `\u003cuse\u003e`\n\n## Installation\n\nFollow the steps below to install LunaSVG using either [CMake](https://cmake.org/) or [Meson](https://mesonbuild.com/).\n\n### Using CMake\n\n```bash\ngit clone https://github.com/sammycage/lunasvg.git\ncd lunasvg\ncmake -B build .\ncmake --build build\ncmake --install build\n```\n\nAfter installing LunaSVG, you can include the library in your CMake projects using `find_package`:\n\n```cmake\nfind_package(lunasvg REQUIRED)\n\n# Link LunaSVG to your target\ntarget_link_libraries(your_target_name PRIVATE lunasvg::lunasvg)\n```\n\nAlternatively, you can use CMake's `FetchContent` to include LunaSVG directly in your project without needing to install it first:\n\n```cmake\ninclude(FetchContent)\nFetchContent_Declare(\n    lunasvg\n    GIT_REPOSITORY https://github.com/sammycage/lunasvg.git\n    GIT_TAG master  # Specify the desired branch or tag\n)\nFetchContent_MakeAvailable(lunasvg)\n\n# Link LunaSVG to your target\ntarget_link_libraries(your_target_name PRIVATE lunasvg::lunasvg)\n```\n\nReplace `your_target_name` with the name of your executable or library target.\n\nBuild Options\nLunaSVG provides several build options that can be configured using -D flags when running cmake. Below is a list of available options:\n\nUSE_SYSTEM_PLUTOVG (default: OFF): Use the system-installed plutovg library (version 1.0.0 or higher) instead of the bundled submodule. If the system library is not found, the build will fall back to using the submodule.\nExample:\n\n```bash\ncmake -B build -DUSE_SYSTEM_PLUTOVG=ON .\ncmake --build build\n```\n\n### Using Meson\n\n```bash\ngit clone https://github.com/sammycage/lunasvg.git\ncd lunasvg\nmeson setup build\nmeson compile -C build\nmeson install -C build\n```\n\nAfter installing LunaSVG, you can include the library in your Meson projects using the `dependency` function:\n\n```meson\nlunasvg_dep = dependency('lunasvg', required: true)\n```\n\nAlternatively, add `lunasvg.wrap` to your `subprojects` directory to include LunaSVG directly in your project without needing to install it first. Create a file named `lunasvg.wrap` with the following content:\n\n```ini\n[wrap-git]\nurl = https://github.com/sammycage/lunasvg.git\nrevision = head\ndepth = 1\n\n[provide]\nlunasvg = lunasvg_dep\n```\n\nYou can retrieve the dependency from the wrap fallback with:\n\n```meson\nlunasvg_dep = dependency('lunasvg', fallback: ['lunasvg', 'lunasvg_dep'])\n```\n\n## Demo\n\nLunaSVG provides a command-line tool `svg2png` for converting SVG files to PNG format.\n\n### Usage:\n```bash\nsvg2png [filename] [resolution] [bgColor]\n```\n\n### Examples:\n```bash\n$ svg2png input.svg\n$ svg2png input.svg 512x512\n$ svg2png input.svg 512x512 0xff00ffff\n```\n\n## Projects Using LunaSVG\n\n- [OpenSiv3D](https://github.com/Siv3D/OpenSiv3D)\n- [PICsimLab](https://github.com/lcgamboa/picsimlab)\n- [MoneyManagerEx](https://github.com/moneymanagerex/moneymanagerex)\n- [RmlUi](https://github.com/mikke89/RmlUi)\n- [EKA2L1](https://github.com/EKA2L1/EKA2L1)\n- [ObEngine](https://github.com/ObEngine/ObEngine)\n- [OTTO](https://github.com/bitfieldaudio/OTTO)\n- [EmulationStation-DE](https://gitlab.com/es-de/emulationstation-de)\n- [SvgBooga](https://github.com/etodanik/SvgBooga/tree/main)\n- [Dear ImGui](https://github.com/ocornut/imgui)\n- [Multi Theft Auto: San Andreas](https://github.com/multitheftauto/mtasa-blue)\n- [eScada Solutions](https://www.escadasolutions.com)\n- [CARLA Simulator](https://carla.org/)\n- [AUI Framework](https://github.com/aui-framework/aui)\n- [Software Companions](http://www.softwarecompanions.com)\n\n## License\n\nLunaSVG is licensed under the MIT License, see [LICENSE](https://github.com/sammycage/lunasvg/blob/master/LICENSE) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsammycage%2Flunasvg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsammycage%2Flunasvg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsammycage%2Flunasvg/lists"}