{"id":22296154,"url":"https://github.com/kakwa/libemf2svg","last_synced_at":"2025-10-10T12:43:20.436Z","repository":{"id":20947604,"uuid":"24236062","full_name":"kakwa/libemf2svg","owner":"kakwa","description":"Microsoft (MS) EMF to SVG conversion library","archived":false,"fork":false,"pushed_at":"2024-08-20T01:01:39.000Z","size":12710,"stargazers_count":106,"open_issues_count":22,"forks_count":32,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-09-17T03:40:19.131Z","etag":null,"topics":["c","emf","microsoft","ms-emf","svg","svg-conversion-library"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kakwa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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}},"created_at":"2014-09-19T15:58:47.000Z","updated_at":"2025-08-21T14:35:53.000Z","dependencies_parsed_at":"2024-12-03T17:44:58.577Z","dependency_job_id":"f408e45f-47e6-4165-af6d-3d35cc3ebc7d","html_url":"https://github.com/kakwa/libemf2svg","commit_stats":{"total_commits":511,"total_committers":9,"mean_commits":56.77777777777778,"dds":"0.046966731898238745","last_synced_commit":"821a40f857cb429bed52c9b1b4c946fbfaff2f55"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/kakwa/libemf2svg","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kakwa%2Flibemf2svg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kakwa%2Flibemf2svg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kakwa%2Flibemf2svg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kakwa%2Flibemf2svg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kakwa","download_url":"https://codeload.github.com/kakwa/libemf2svg/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kakwa%2Flibemf2svg/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279003894,"owners_count":26083641,"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","status":"online","status_checked_at":"2025-10-10T02:00:06.843Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["c","emf","microsoft","ms-emf","svg","svg-conversion-library"],"created_at":"2024-12-03T17:44:24.901Z","updated_at":"2025-10-10T12:43:20.415Z","avatar_url":"https://github.com/kakwa.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"libemf2svg\n==========\n\n[![Join the chat at https://gitter.im/kakwa/libemf2svg](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/kakwa/libemf2svg?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n[![Build Status](https://travis-ci.org/kakwa/libemf2svg.svg?branch=master)](https://travis-ci.org/kakwa/libemf2svg)\n[![Coverage Status](https://coveralls.io/repos/github/kakwa/libemf2svg/badge.svg?branch=gcov)](https://coveralls.io/github/kakwa/libemf2svg?branch=gcov)\n\nMS EMF (Enhanced Metafile) to SVG conversion library.\n\nMotivation\n----------\n\nBy themselves, EMF/EMF+ files are rare in the wild. However, they are frequently embedded inside other MS file formats.\n\nThis project was started to properly convert Visio stencils (.VSS) to svg and be able to reuse public stencils \nin other environments than MS Visio (see [libvisio2svg](https://github.com/kakwa/libvisio2svg)).\n\nHowever this project could be use beyond its original motivations to handle emf blobs in any MS formats.\n\nOutput example\n--------------\n\n![Example](https://cdn.rawgit.com/kakwa/libemf2svg/master/goodies/demo-example.svg)\n\nDependencies\n------------\n\n* libiconv\n* libpng\n* libfontconfig\n* libfreetype\n\nInstalling the dependencies on Debian:\n\n```bash\n# compiler\napt-get install gcc g++ \n# or \napt-get install clang\n\n# build deps\napt-get install cmake pkg-config\n\n# library deps with their headers\napt-get install libpng-dev libc6-dev libfontconfig1-dev libfreetype6-dev zlib1g-dev\n```\n\nInstalling the dependencies on OS X:\n```bash\n$ brew install argp-standalone\n```\n\nInstalling the dependencies on RHEL/CentOS/Fedora:\n```bash\nyum install cmake libpng-devel freetype-devel fontconfig-devel gcc-c++ gcc\n```\n\nAlso note that in some rare cases, to properly handle text fields (ETO_GLYPH_INDEX flag), the ttf font\nused by the documents must be present and indexed (fontconfig) on your system.\n\nBuilding\n--------\n\nCommands to build this project:\n\n```bash\n\n# options: \n# * [-DUSE_CLANG=on]: use clang instead of gcc\n# * [-DSTATIC=on]: build static library\n# * [-DDEBUG=on]: compile with debugging symbols\n#\n# CMAKE_INSTALL_PREFIX is optional, default is /usr/local/\n$ cmake . -DCMAKE_INSTALL_PREFIX=/usr/\n\n# compilation\n$ make\n\n# installation\n$ make install\n```\n\nCommand line tool\n-----------------\n\n```bash\n$ ./emf2svg-conv --help\nUsage: emf2svg-conv [OPTION...] -i FILE -o FILE\nemf2svg -- Enhanced Metafile to SVG converter\n\n  -h, --height=HEIGHT        Max height in px\n  -i, --input=FILE           Input EMF file\n  -o, --output=FILE          Output SVG file\n  -p, --emfplus              Handle EMF+ records\n  -v, --verbose              Produce verbose output\n  -w, --width=WIDTH          Max width in px\n  -?, --help                 Give this help list\n      --usage                Give a short usage message\n      --version              Print program version\n  -V, --version              Print emf2svg version\n\nMandatory or optional arguments to long options are also mandatory or optional\nfor any corresponding short options.\n\nReport bugs to https://github.com/kakwa/libemf2svg/issues.\n\n# usage example:\n$ ./emf2svg-conv -i ./tests/resources/emf/test-037.emf -o example.svg -v\n```\n\nLibrary\n-------\n\nShorten examples:\n\n\nConversion from EMF to SVG ([complete example here](https://github.com/kakwa/libemf2svg/blob/master/goodies/example.c)):\n```C\n#include \u003cemf2svg.h\u003e\n//[...]\nint main(int argc, char *argv[]){\n\n    /* emf content size */\n    size_t emf_size;\n    /* emf content */\n    char * emf_content;\n    /* svg output string */\n    char *svg_out = NULL;\n    /* svg output length */\n    size_t svg_out_len = 0;\n\n    //[...]\n\n    /*************************** options settings **************************/\n\n    /* allocate the options structure) */\n    generatorOptions *options = (generatorOptions *)calloc(1, \\\n            sizeof(generatorOptions));\n    /* debugging flag (prints the emf record in stdout if true) */\n    options-\u003everbose = true;\n    /* emf+ flag (handles emf+ records if true) */\n    options-\u003eemfplus = true;\n    /* if a custom xml/svg namespace is needed (keep empty in doubt) */\n    options-\u003enameSpace = (char *)\"svg\";\n    /* includes the svg start and stop tags (set to false if the result\n     * of this call is meant to be used inside another svg) */\n    options-\u003esvgDelimiter = true;\n    /* image width in px (set to 0 to use the original emf device width) */\n    options-\u003eimgWidth = 0;\n    /* image height in px (set to 0 to use the original emf device height) */\n    options-\u003eimgHeight = 0;\n\n    /***************************** conversion ******************************/\n\n    int ret = emf2svg(emf_content, emf_size, \u0026svg_out, \u0026svg_out_len, options);\n\n    /***********************************************************************/\n\n    //[...]\n}\n```\n\nCheck document for EMF+ record presence ([complete example here](https://github.com/kakwa/libemf2svg/blob/master/goodies/check_emfp.c)):\n```C\nint main(int argc, char *argv[]){\n\n    /* emf content size */\n    size_t emf_size;\n    /* emf content */\n    char * emf_content;\n    /* svg output string */\n    char *svg_out = NULL;\n    /* svg output length */\n    size_t svg_out_len = 0;\n\n    bool emfplus;\n    int ret = emf2svg_is_emfplus(emf_content, emf_size, \u0026emfplus);\n    if(emfplus)\n        fprintf(stdout,\"%s contains EMF+ records\\n\", file_name);\n}\n```\n\nSee [./src/conv/emf2svg.cpp](https://github.com/kakwa/libemf2svg/blob/master/src/conv/emf2svg.cpp) for a real life example.\n\nEMF/EMF+ record type coverage\n-----------------------------\n\nEMF RECORDS:\n\n|   Status  | Count | Percent |\n|:---------:|:-----:|:-------:|\n| Supported |   37  | [  35%] |\n| Partial   |   33  | [  31%] |\n| Unused    |    2  | [   1%] |\n| Ignored   |   33  | [  31%] |\n| Total     |  105  |         |\n\nEMF+ RECORDS:\n\n|   Status  | Count | Percent |\n|:---------:|:-----:|:-------:|\n| Supported |    0  | [   0%] |\n| Partial   |    0  | [   0%] |\n| Unused    |    0  | [   0%] |\n| Ignored   |   85  | [ 100%] |\n| Total     |   85  |         |\n\nChangeLogs\n----------\n\n1.1.0:\n\n* add handling of font index encoding\n* add fontconfig dependency\n* add freetype dependency\n* add common variables LIB_INSTALL_DIR, BIN_INSTALL_DIR, INCLUDE_INSTALL_DIR to set install directories\n\n1.0.3:\n\n* Fixing compilation on CentOS 7 (work around argp bug)\n\n1.0.2:\n\n* broken release, please don't use\n\n1.0.1:\n\n* cleaner handling of memstream on OSX (don't install libmemstream, just embed it)\n\n1.0.0:\n\n* better cmake regarding finding dependency libraries (libpng)\n* /!\\ API break, must pass an additionnal argument to emf2svg function:\n```diff\n--- a/goodies/old.c\n+++ b/goodies/new.c\n@@ -22,6 +22,8 @@ int main(int argc, char *argv[]){\n     char * emf_content = mmap(0, emf_size, PROT_READ, MAP_PRIVATE, fd, 0);\n     /* svg output string */\n     char *svg_out = NULL;\n+    /* svg output length */\n+    size_t svg_out_len;\n \n     /*************************** options settings **************************/\n \n@@ -44,7 +46,7 @@ int main(int argc, char *argv[]){\n \n     /***************************** conversion ******************************/\n \n-    int ret = emf2svg(emf_content, emf_size, \u0026svg_out, options);\n+    int ret = emf2svg(emf_content, emf_size, \u0026svg_out, \u0026svg_out_len, options);\n \n     /***********************************************************************/\n```\n* general cleanup of the project (remove external files not needed)\n\n0.5.1:\n\n* fix build on OS X\n\n0.5.0:\n\n* add alpha layer handling in bitmap blobs conversion\n* add brush patterns\n\n0.4.0:\n\n* fix text orientation\n* fix origin handling in special case\n\n0.3.0:\n\n* completly rework how the origin is calculated, it now takes correctly into account both viewport and window orgs\n\n0.2.0:\n\n* code reorganization\n* add support for ANGLEARC, EMRSTRETCHBLT, EMRBITBLT and more\n* add handling of bitmap, RLE4 and RLE8 image blobs\n* add some rough handling of clipping forms\n* fix text rendering to not collapse spaces\n\n0.1.0:\n\n* first version\n\nDevelopment\n-----------\n\nGeneral source code organisation:\n\n* [./src/lib/emf2svg.c](https://github.com/kakwa/libemf2svg/blob/master/src/lib/emf2svg.c): API entry point.\n* [./src/lib/emf2svg_rec_*](https://github.com/kakwa/libemf2svg/blob/master/src/lib/): EMF record handlers\n* [./src/lib/emf2svg_print.c](https://github.com/kakwa/libemf2svg/blob/master/src/lib/emf2svg_print.c): EMF record printer (debugging).\n* [./src/lib/pmf2svg.c](https://github.com/kakwa/libemf2svg/blob/master/src/lib/pmf2svg.c): EMF+ record handler.\n* [./src/lib/pmf2svg_print.c](https://github.com/kakwa/libemf2svg/blob/master/src/lib/pmf2svg_print.c): EMF+ record printer (debugging).\n* [./src/conv/emf2svg.cpp](https://github.com/kakwa/libemf2svg/blob/master/src/conv/emf2svg.cpp): Command line tool.\n* [./deps](https://github.com/kakwa/libemf2svg/blob/master/deps): external dependencies.\n\nUseful links:\n\n* [MS-EMF](http://msdn.microsoft.com/en-us/library/cc230514.aspx): EMF specifications.\n* [MS-EMF+](http://msdn.microsoft.com/en-us/library/cc230724.aspx): EMF+ specifications.\n* [MS-WMF](http://msdn.microsoft.com/en-us/library/cc250370.aspx): WMF specifications.\n* [GDI](https://msdn.microsoft.com/fr-fr/library/windows/desktop/dd145203(v=vs.85).aspx): GDI specification (clearer than EMF in explaining how it works).\n* [SVG](http://www.w3.org/TR/SVG/Overview.html): SVG specifications.\n\nTesting\n-------\n\n* Stats on the number of emf records covered:\n\n```bash\n$ ./tests/resources/coverage.sh\n```\n\n* Fuzzing on the library:\n\nUsing American Fuzzy Lop:\n\n\n```bash\n# remove big files from test pool\n$ mkdir ./tmp\n$ find tests/resources/emf -size +1M -name \"*.emf\" -exec mv {} ./tmp \\; \n\n# compile with afl compiler\n$ cmake -DCMAKE_CXX_COMPILER=afl-clang++ -DCMAKE_C_COMPILER=afl-clang .\n$ make\n\n# run afl (see man for more advanced usage)\n$ afl-fuzz -i tests/resources/emf -o out/ -t 10000 -- ./emf2svg-conv -i '@@' -o out/ \n\n# restore the files\nmv ./tmp/* tests/resources/emf\n```\n\n* Check correctness and memory leaks (xmllint and valgrind needed):\n\n```bash\n# options: -n to disable valgrind tests, -v for verbose output \n# see -h for complete list of options\n$ ./tests/resources/check_correctness.sh #[-n] [-v]\n\n# generated svg:\n$ ls tests/out/test-*\ntests/out/test-000.emf.svg  tests/out/test-051.emf.svg\n[...]\n```\n\nThe emf files used for these checks are located in [./tests/resources/emf/](https://github.com/kakwa/libemf2svg/blob/master/tests/resources/emf/).\n\nUseful Commands\n---------------\n\nTo build, run on emf test files and visualize (with geeqie):\n```bash\n$ cmake .\u0026\u0026 \\\n    make \u0026\u0026\\\n    \"./tests/resources/check_correctness.sh\" -n \u0026\u0026\\\n    geeqie \"tests/out\"\n```\n\nTo check against corrupted emf:\n```bash\n$ cmake -DDEBUG=ON . \u0026\u0026\\\n    make \u0026\u0026\\\n    \"./tests/resources/check_correctness.sh\" -sxN \\\n    -e \"./tests/resources/emf-corrupted/\"\n```\n\nTo print records index in svg as comments:\n\n```bash\n$ cmake -DINDEX=ON . \u0026\u0026 make\n```\n\nTo reformat/reindent the code (clang-format):\n\n```bash\n$ ./goodies/format\n```\n\nContributing\n------------\n\nContribution are welcomed.\nNothing special here, it's the usual \"fork; commit(s); pull request\".\nOnly one thing however, run `./goodies/format` (clang-format) before the pull request.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkakwa%2Flibemf2svg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkakwa%2Flibemf2svg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkakwa%2Flibemf2svg/lists"}