From b6aa55bcf7858f0922738cf373304f058fec3085 Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Fri, 12 Jan 2024 19:59:40 -0500 Subject: [PATCH 1/7] Script for icon gridding --- CONTRIBUTING.md | 6 + package-lock.json | 663 ++++++++++++++++++++++++++++++++++++++----- package.json | 2 + scripts/icon_grid.ts | 69 +++++ 4 files changed, 669 insertions(+), 71 deletions(-) create mode 100644 scripts/icon_grid.ts diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 216ac2039..41a359531 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -269,6 +269,12 @@ The MUTCD’s standard colors are designed for high-contrast backgrounds and leg See the [developer tools](dev/README.md) for an importable, Inkscape-compatible palette file. +### Icon Grid Alignment + +There is a utility script called icon_grid that will generate a pixel grid on an SVG. This can be used to check how well the icon will align to the pixel grid. Run this utility as follows: + +`npm run icon_grid -- icons/poi_fuel.svg` + ### Font Sizes Shields should target 8-14px text actual-size character heights for readability: diff --git a/package-lock.json b/package-lock.json index 7833bdf99..51fca5472 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,6 +29,7 @@ "@types/color-namer": "^1.3.0", "@types/mocha": "^10.0.1", "@types/node": "^20.8.4", + "@types/sharp": "^0.32.0", "benchmark": "^2.1.4", "canvas": "^2.11.0", "chai": "^4.3.7", @@ -74,6 +75,91 @@ "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, + "node_modules/@basemaps/sprites/node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@basemaps/sprites/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@basemaps/sprites/node_modules/sharp": { + "version": "0.32.6", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz", + "integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.2", + "node-addon-api": "^6.1.0", + "prebuild-install": "^7.1.1", + "semver": "^7.5.4", + "simple-get": "^4.0.1", + "tar-fs": "^3.0.4", + "tunnel-agent": "^0.6.0" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@basemaps/sprites/node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-0.45.0.tgz", + "integrity": "sha512-Txumi3td7J4A/xTTwlssKieHKTGl3j4A1tglBx72auZ49YK7ePY6XZricgIg9mnZT4xPfA+UPCUdnhRuEFDL+w==", + "dev": true, + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@esbuild/android-arm": { "version": "0.17.19", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz", @@ -426,6 +512,456 @@ "node": ">=12" } }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.2.tgz", + "integrity": "sha512-itHBs1rPmsmGF9p4qRe++CzCgd+kFYktnsoR1sbIAfsRMrJZau0Tt1AH9KVnufc2/tU02Gf6Ibujx+15qRE03w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.1" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.2.tgz", + "integrity": "sha512-/rK/69Rrp9x5kaWBjVN07KixZanRr+W1OiyKdXcbjQD6KbW+obaTeBBtLUAtbBsnlTTmWthw99xqoOS7SsySDg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.1" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.1.tgz", + "integrity": "sha512-kQyrSNd6lmBV7O0BUiyu/OEw9yeNGFbQhbxswS1i6rMDwBBSX+e+rPzu3S+MwAiGU3HdLze3PanQ4Xkfemgzcw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "macos": ">=11", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.1.tgz", + "integrity": "sha512-eVU/JYLPVjhhrd8Tk6gosl5pVlvsqiFlt50wotCvdkFGf+mDNBJxMh+bvav+Wt3EBnNZWq8Sp2I7XfSjm8siog==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "macos": ">=10.13", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.1.tgz", + "integrity": "sha512-FtdMvR4R99FTsD53IA3LxYGghQ82t3yt0ZQ93WMZ2xV3dqrb0E8zq4VHaTOuLEAuA83oDawHV3fd+BsAPadHIQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.1.tgz", + "integrity": "sha512-bnGG+MJjdX70mAQcSLxgeJco11G+MxTz+ebxlz8Y3dxyeb3Nkl7LgLI0mXupoO+u1wRNx/iRj5yHtzA4sde1yA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.1.tgz", + "integrity": "sha512-3+rzfAR1YpMOeA2zZNp+aYEzGNWK4zF3+sdMxuCS3ey9HhDbJ66w6hDSHDMoap32DueFwhhs3vwooAB2MaK4XQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.1.tgz", + "integrity": "sha512-3NR1mxFsaSgMMzz1bAnnKbSAI+lHXVTqAHgc1bgzjHuXjo4hlscpUxc0vFSAPKI3yuzdzcZOkq7nDPrP2F8Jgw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.1.tgz", + "integrity": "sha512-5aBRcjHDG/T6jwC3Edl3lP8nl9U2Yo8+oTl5drd1dh9Z1EBfzUKAJFUDTDisDjUwc7N4AjnPGfCA3jl3hY8uDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.1.tgz", + "integrity": "sha512-dcT7inI9DBFK6ovfeWRe3hG30h51cBAP5JXlZfx6pzc/Mnf9HFCQDLtYf4MCBjxaaTfjCCjkBxcy3XzOAo5txw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.2.tgz", + "integrity": "sha512-Fndk/4Zq3vAc4G/qyfXASbS3HBZbKrlnKZLEJzPLrXoJuipFNNwTes71+Ki1hwYW5lch26niRYoZFAtZVf3EGA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.1" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.2.tgz", + "integrity": "sha512-pz0NNo882vVfqJ0yNInuG9YH71smP4gRSdeL09ukC2YLE6ZyZePAlWKEHgAzJGTiOh8Qkaov6mMIMlEhmLdKew==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.1" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.2.tgz", + "integrity": "sha512-MBoInDXDppMfhSzbMmOQtGfloVAflS2rP1qPcUIiITMi36Mm5YR7r0ASND99razjQUpHTzjrU1flO76hKvP5RA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.1" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.2.tgz", + "integrity": "sha512-xUT82H5IbXewKkeF5aiooajoO1tQV4PnKfS/OZtb5DDdxS/FCI/uXTVZ35GQ97RZXsycojz/AJ0asoz6p2/H/A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.1" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.2.tgz", + "integrity": "sha512-F+0z8JCu/UnMzg8IYW1TMeiViIWBVg7IWP6nE0p5S5EPQxlLd76c8jYemG21X99UzFwgkRo5yz2DS+zbrnxZeA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.1" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.2.tgz", + "integrity": "sha512-+ZLE3SQmSL+Fn1gmSaM8uFusW5Y3J9VOf+wMGNnTtJUMUxFhv+P4UPaYEYT8tqnyYVaOVGgMN/zsOxn9pSsO2A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.1" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.2.tgz", + "integrity": "sha512-fLbTaESVKuQcpm8ffgBD7jLb/CQLcATju/jxtTXR1XCLwbOQt+OL5zPHSDMmp2JZIeq82e18yE0Vv7zh6+6BfQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "optional": true, + "dependencies": { + "@emnapi/runtime": "^0.45.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.2.tgz", + "integrity": "sha512-okBpql96hIGuZ4lN3+nsAjGeggxKm7hIRu9zyec0lnfB8E7Z6p95BuRZzDDXZOl2e8UmR4RhYt631i7mfmKU8g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.2.tgz", + "integrity": "sha512-E4magOks77DK47FwHUIGH0RYWSgRBfGdK56kIHSVeB9uIS4pPFr4N2kIVsXdQQo4LzOsENKV5KAhRlRL7eMAdg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -719,6 +1255,16 @@ "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.2.tgz", "integrity": "sha512-EDrLIPaPXOZqDjrkzxxbX7UlJSeQVgah3i0aA4pOSzmK9zq3BIh7/MZIQxED7slJByvKM4Gc6Hypyu2lJzh3SQ==" }, + "node_modules/@types/sharp": { + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/@types/sharp/-/sharp-0.32.0.tgz", + "integrity": "sha512-OOi3kL+FZDnPhVzsfD37J88FNeZh6gQsGcLc95NbeURRGvmSjeXiDcyWzF2o3yh/gQAUn2uhh/e+CPCa5nwAxw==", + "deprecated": "This is a stub types definition. sharp provides its own type definitions, so you do not need this installed.", + "dev": true, + "dependencies": { + "sharp": "*" + } + }, "node_modules/@xmldom/xmldom": { "version": "0.8.10", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", @@ -1990,10 +2536,13 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/function.prototype.name": { "version": "1.1.5", @@ -3273,9 +3822,9 @@ "dev": true }, "node_modules/node-abi": { - "version": "3.51.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.51.0.tgz", - "integrity": "sha512-SQkEP4hmNWjlniS5zdnfIXTk1x7Ome85RDzHlTbBtzE97Gfwz/Ipw4v/Ryk20DWIy3yCNVLVlGKApCnmvYoJbA==", + "version": "3.54.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.54.0.tgz", + "integrity": "sha512-p7eGEiQil0YUV3ItH4/tBb781L5impVmmx2E9FRKF7d18XXzp4PGT2tdYMFY6wQqgxD0IwNZOiSJ0/K0fSi/OA==", "dev": true, "dependencies": { "semver": "^7.3.5" @@ -4348,78 +4897,43 @@ "dev": true }, "node_modules/sharp": { - "version": "0.32.6", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz", - "integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==", + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.2.tgz", + "integrity": "sha512-WlYOPyyPDiiM07j/UO+E720ju6gtNtHjEGg5vovUk1Lgxyjm2LFO+37Nt/UI3MMh2l6hxTWQWi7qk3cXJTutcQ==", "dev": true, "hasInstallScript": true, "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.2", - "node-addon-api": "^6.1.0", - "prebuild-install": "^7.1.1", - "semver": "^7.5.4", - "simple-get": "^4.0.1", - "tar-fs": "^3.0.4", - "tunnel-agent": "^0.6.0" + "semver": "^7.5.4" }, "engines": { - "node": ">=14.15.0" + "libvips": ">=8.15.1", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" - } - }, - "node_modules/sharp/node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "dependencies": { - "mimic-response": "^3.1.0" }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/sharp/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/sharp/node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.2", + "@img/sharp-darwin-x64": "0.33.2", + "@img/sharp-libvips-darwin-arm64": "1.0.1", + "@img/sharp-libvips-darwin-x64": "1.0.1", + "@img/sharp-libvips-linux-arm": "1.0.1", + "@img/sharp-libvips-linux-arm64": "1.0.1", + "@img/sharp-libvips-linux-s390x": "1.0.1", + "@img/sharp-libvips-linux-x64": "1.0.1", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.1", + "@img/sharp-libvips-linuxmusl-x64": "1.0.1", + "@img/sharp-linux-arm": "0.33.2", + "@img/sharp-linux-arm64": "0.33.2", + "@img/sharp-linux-s390x": "0.33.2", + "@img/sharp-linux-x64": "0.33.2", + "@img/sharp-linuxmusl-arm64": "0.33.2", + "@img/sharp-linuxmusl-x64": "0.33.2", + "@img/sharp-wasm32": "0.33.2", + "@img/sharp-win32-ia32": "0.33.2", + "@img/sharp-win32-x64": "0.33.2" } }, "node_modules/shebang-command": { @@ -4703,9 +5217,9 @@ "dev": true }, "node_modules/streamx": { - "version": "2.15.5", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.5.tgz", - "integrity": "sha512-9thPGMkKC2GctCzyCUjME3yR03x2xNo0GPKGkRw2UMYN+gqWa9uqpyNWhmsNCutU5zHmkUum0LsCRQTXUgUCAg==", + "version": "2.15.6", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.6.tgz", + "integrity": "sha512-q+vQL4AAz+FdfT137VF69Cc/APqUbxy+MDOImRrMvchJpigHj9GksgDU2LYbO9rx7RX6osWgxJB2WxhYv4SZAw==", "dev": true, "dependencies": { "fast-fifo": "^1.1.0", @@ -5003,6 +5517,13 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "dev": true }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true, + "optional": true + }, "node_modules/tsx": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.6.2.tgz", diff --git a/package.json b/package.json index ecef53ce5..95bdd315a 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "code_format:svgo": "svgo -q -f icons/", "extract_layer": "node scripts/extract_layer", "generate_samples": "tsx scripts/generate_samples.ts", + "icon_grid": "tsx scripts/icon_grid.ts", "presprites": "shx rm -rf dist/sprites", "serve": "tsx scripts/serve", "shields": "node scripts/generate_shield_defs.js -o dist/shields.json", @@ -55,6 +56,7 @@ "@types/color-namer": "^1.3.0", "@types/mocha": "^10.0.1", "@types/node": "^20.8.4", + "@types/sharp": "^0.32.0", "benchmark": "^2.1.4", "canvas": "^2.11.0", "chai": "^4.3.7", diff --git a/scripts/icon_grid.ts b/scripts/icon_grid.ts new file mode 100644 index 000000000..75384de5e --- /dev/null +++ b/scripts/icon_grid.ts @@ -0,0 +1,69 @@ +import sharp from "sharp"; +import fs from "fs"; +import path from "path"; + +const svgFilename = process.argv[2]; +const outputFilenameBase = path.parse(svgFilename).name; +const outputFilename = `${outputFilenameBase}_preview.png`; +const scale = 40; + +// Function to generate a pixel grid +function generateGridPattern(): Buffer { + const gridSvg = ` + + + + + `; + return Buffer.from(gridSvg); +} + +// Convert and scale SVG +async function convertAndScaleSVG(svgFilename: string): Promise { + try { + const svgBuffer = fs.readFileSync(svgFilename); + + // Get dimensions of the original SVG + const metadata = await sharp(svgBuffer).metadata(); + const width = metadata.width! * scale; + const height = metadata.height! * scale; + + // Resize the SVG + const resizedSvgBuffer = await sharp(svgBuffer, { + density: 72 * scale, + }) + .resize(width, height) + .toBuffer(); + + // Generate a pixel grid pattern + const gridPattern = generateGridPattern(); + + // Composite the scaled image over the grid + sharp({ + create: { + width: width, + height: height, + channels: 4, + background: { r: 255, g: 255, b: 255, alpha: 0 }, + }, + }) + .composite([ + { input: resizedSvgBuffer, blend: "over" }, + { input: generateGridPattern(), tile: true, blend: "over" }, + ]) + .toFile(outputFilename) + .then(() => console.log(`Wrote ${outputFilename}`)) + .catch((err) => console.error(err)); + } catch (error) { + console.error("Error:", error); + } +} + +if (!svgFilename) { + console.error("Please provide an SVG filename."); + process.exit(1); +} + +convertAndScaleSVG(svgFilename); From 07d90adb2e3bf1a8ba60c48efb60da3d3d7893cb Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Fri, 12 Jan 2024 20:25:37 -0500 Subject: [PATCH 2/7] Fix odd/even alignment --- scripts/icon_grid.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/scripts/icon_grid.ts b/scripts/icon_grid.ts index 75384de5e..61e6a7b4e 100644 --- a/scripts/icon_grid.ts +++ b/scripts/icon_grid.ts @@ -8,14 +8,15 @@ const outputFilename = `${outputFilenameBase}_preview.png`; const scale = 40; // Function to generate a pixel grid -function generateGridPattern(): Buffer { +function generateGridPattern(xOffset: number, yOffset: number): Buffer { const gridSvg = ` - - + - `; return Buffer.from(gridSvg); } @@ -37,8 +38,11 @@ async function convertAndScaleSVG(svgFilename: string): Promise { .resize(width, height) .toBuffer(); + const xOffset: number = width % 2 == 0 ? scale / 2 : 0; + const yOffset: number = height % 2 == 0 ? scale / 2 : 0; + // Generate a pixel grid pattern - const gridPattern = generateGridPattern(); + const gridPattern = generateGridPattern(xOffset, yOffset); // Composite the scaled image over the grid sharp({ @@ -51,7 +55,7 @@ async function convertAndScaleSVG(svgFilename: string): Promise { }) .composite([ { input: resizedSvgBuffer, blend: "over" }, - { input: generateGridPattern(), tile: true, blend: "over" }, + { input: gridPattern, tile: true, blend: "over" }, ]) .toFile(outputFilename) .then(() => console.log(`Wrote ${outputFilename}`)) From 938d897176f16f9a504cc399b8c58c4181d626a8 Mon Sep 17 00:00:00 2001 From: Josh Lee Date: Mon, 15 Jan 2024 09:58:08 -0500 Subject: [PATCH 3/7] Correct dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Need to actually depend on sharp, not just type definitions And the type definitions actually say  WARN  deprecated @types/sharp@0.32.0: This is a stub types definition. sharp provides its own type definitions, so you do not need this installed. So remove them --- package-lock.json | 12 +----------- package.json | 2 +- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 51fca5472..623957d73 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,7 +29,6 @@ "@types/color-namer": "^1.3.0", "@types/mocha": "^10.0.1", "@types/node": "^20.8.4", - "@types/sharp": "^0.32.0", "benchmark": "^2.1.4", "canvas": "^2.11.0", "chai": "^4.3.7", @@ -44,6 +43,7 @@ "open": "^8.4.2", "pbf": "^3.2.1", "prettier": "^2.3.2", + "sharp": "^0.33.2", "shx": "^0.3.4", "svgo": "^2.8.0", "tsx": "^4.6.2", @@ -1255,16 +1255,6 @@ "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.2.tgz", "integrity": "sha512-EDrLIPaPXOZqDjrkzxxbX7UlJSeQVgah3i0aA4pOSzmK9zq3BIh7/MZIQxED7slJByvKM4Gc6Hypyu2lJzh3SQ==" }, - "node_modules/@types/sharp": { - "version": "0.32.0", - "resolved": "https://registry.npmjs.org/@types/sharp/-/sharp-0.32.0.tgz", - "integrity": "sha512-OOi3kL+FZDnPhVzsfD37J88FNeZh6gQsGcLc95NbeURRGvmSjeXiDcyWzF2o3yh/gQAUn2uhh/e+CPCa5nwAxw==", - "deprecated": "This is a stub types definition. sharp provides its own type definitions, so you do not need this installed.", - "dev": true, - "dependencies": { - "sharp": "*" - } - }, "node_modules/@xmldom/xmldom": { "version": "0.8.10", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", diff --git a/package.json b/package.json index 95bdd315a..a55d536da 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,6 @@ "@types/color-namer": "^1.3.0", "@types/mocha": "^10.0.1", "@types/node": "^20.8.4", - "@types/sharp": "^0.32.0", "benchmark": "^2.1.4", "canvas": "^2.11.0", "chai": "^4.3.7", @@ -71,6 +70,7 @@ "open": "^8.4.2", "pbf": "^3.2.1", "prettier": "^2.3.2", + "sharp": "^0.33.2", "shx": "^0.3.4", "svgo": "^2.8.0", "tsx": "^4.6.2", From 0a457ad6fdf7c76570a857d5237fe78559eb62bf Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Mon, 15 Jan 2024 13:46:28 -0500 Subject: [PATCH 4/7] Update scripts/icon_grid.ts Co-authored-by: Josh Lee --- scripts/icon_grid.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/icon_grid.ts b/scripts/icon_grid.ts index 61e6a7b4e..59c8cb65e 100644 --- a/scripts/icon_grid.ts +++ b/scripts/icon_grid.ts @@ -70,4 +70,9 @@ if (!svgFilename) { process.exit(1); } -convertAndScaleSVG(svgFilename); +try { + await convertAndScaleSVG(svgFilename); +} catch (error) { + console.error("Error: ", error); + process.exit(1); +} From 407ff3785228737a809ea6fa37926b6efe420190 Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Mon, 15 Jan 2024 13:46:34 -0500 Subject: [PATCH 5/7] Update scripts/icon_grid.ts Co-authored-by: Josh Lee --- scripts/icon_grid.ts | 65 ++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 35 deletions(-) diff --git a/scripts/icon_grid.ts b/scripts/icon_grid.ts index 59c8cb65e..e5e9420b4 100644 --- a/scripts/icon_grid.ts +++ b/scripts/icon_grid.ts @@ -23,46 +23,41 @@ function generateGridPattern(xOffset: number, yOffset: number): Buffer { // Convert and scale SVG async function convertAndScaleSVG(svgFilename: string): Promise { - try { - const svgBuffer = fs.readFileSync(svgFilename); + const svgBuffer = fs.readFileSync(svgFilename); - // Get dimensions of the original SVG - const metadata = await sharp(svgBuffer).metadata(); - const width = metadata.width! * scale; - const height = metadata.height! * scale; + // Get dimensions of the original SVG + const metadata = await sharp(svgBuffer).metadata(); + const width = metadata.width! * scale; + const height = metadata.height! * scale; - // Resize the SVG - const resizedSvgBuffer = await sharp(svgBuffer, { - density: 72 * scale, - }) - .resize(width, height) - .toBuffer(); + // Resize the SVG + const resizedSvgBuffer = await sharp(svgBuffer, { + density: 72 * scale, + }) + .resize(width, height) + .toBuffer(); - const xOffset: number = width % 2 == 0 ? scale / 2 : 0; - const yOffset: number = height % 2 == 0 ? scale / 2 : 0; + const xOffset: number = width % 2 == 0 ? scale / 2 : 0; + const yOffset: number = height % 2 == 0 ? scale / 2 : 0; - // Generate a pixel grid pattern - const gridPattern = generateGridPattern(xOffset, yOffset); + // Generate a pixel grid pattern + const gridPattern = generateGridPattern(xOffset, yOffset); - // Composite the scaled image over the grid - sharp({ - create: { - width: width, - height: height, - channels: 4, - background: { r: 255, g: 255, b: 255, alpha: 0 }, - }, - }) - .composite([ - { input: resizedSvgBuffer, blend: "over" }, - { input: gridPattern, tile: true, blend: "over" }, - ]) - .toFile(outputFilename) - .then(() => console.log(`Wrote ${outputFilename}`)) - .catch((err) => console.error(err)); - } catch (error) { - console.error("Error:", error); - } + // Composite the scaled image over the grid + await sharp({ + create: { + width, + height, + channels: 4, + background: { r: 255, g: 255, b: 255, alpha: 0 }, + }, + }) + .composite([ + { input: resizedSvgBuffer, blend: "over" }, + { input: gridPattern, tile: true, blend: "over" }, + ]) + .toFile(outputFilename); + console.log(`Wrote ${outputFilename}`); } if (!svgFilename) { From df84136528061aeaa3113db6be7f231be5fc4093 Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Mon, 15 Jan 2024 18:51:25 -0500 Subject: [PATCH 6/7] Light gray background --- scripts/icon_grid.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/icon_grid.ts b/scripts/icon_grid.ts index e5e9420b4..899a7cd3e 100644 --- a/scripts/icon_grid.ts +++ b/scripts/icon_grid.ts @@ -49,7 +49,7 @@ async function convertAndScaleSVG(svgFilename: string): Promise { width, height, channels: 4, - background: { r: 255, g: 255, b: 255, alpha: 0 }, + background: { r: 211, g: 211, b: 211, alpha: 1 }, // Light gray to show white borders }, }) .composite([ From 11897813e6d9ed71df13ccedb0b90358c9a2b26e Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Mon, 15 Jan 2024 18:55:04 -0500 Subject: [PATCH 7/7] offset bugfix --- scripts/icon_grid.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/icon_grid.ts b/scripts/icon_grid.ts index 899a7cd3e..72996e16b 100644 --- a/scripts/icon_grid.ts +++ b/scripts/icon_grid.ts @@ -37,8 +37,8 @@ async function convertAndScaleSVG(svgFilename: string): Promise { .resize(width, height) .toBuffer(); - const xOffset: number = width % 2 == 0 ? scale / 2 : 0; - const yOffset: number = height % 2 == 0 ? scale / 2 : 0; + const xOffset: number = metadata.width! % 2 == 0 ? scale / 2 : 0; + const yOffset: number = metadata.height! % 2 == 0 ? scale / 2 : 0; // Generate a pixel grid pattern const gridPattern = generateGridPattern(xOffset, yOffset);