From 925119fc2ba876eee79af4409b5d95c2663dcd0f Mon Sep 17 00:00:00 2001 From: Garrett Campbell <86264750+gcampbell-msft@users.noreply.github.com> Date: Tue, 15 Oct 2024 14:53:57 -0400 Subject: [PATCH 1/3] update OneLocBuild Task version to 3 (#4130) --- jobs/loc/TranslationsImportExport.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jobs/loc/TranslationsImportExport.yml b/jobs/loc/TranslationsImportExport.yml index 2554bd332..198661375 100644 --- a/jobs/loc/TranslationsImportExport.yml +++ b/jobs/loc/TranslationsImportExport.yml @@ -76,7 +76,7 @@ extends: $token = az account get-access-token --query accessToken --resource $(AzureGuid) -o tsv Write-Host "##vso[task.setvariable variable=AzDO.OneLocBuildToken;issecret=true]${token}" - - task: OneLocBuild@2 + - task: OneLocBuild@3 env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) inputs: From e765b1e85fc68b7965ba28028e3ba5b540360e0a Mon Sep 17 00:00:00 2001 From: DeltaRazero Date: Thu, 17 Oct 2024 20:31:11 +0200 Subject: [PATCH 2/3] Use product icons instead of 'hardcoded' icons (#3737) * Use product icons instead of 'hardcoded' icons - Add a product icon font instead of icons that are unchangable by product icon themes - Add a script using FontForge scripting API for generating product icon font for future use - Remove redundant icons that are already part of codicons * Revert accidental addition of 'languages' contribution entry --- package.json | 114 ++++++----- res/dark/build-icon.svg | 8 - res/dark/clean-configure-icon.svg | 27 --- res/dark/clean-icon.svg | 39 ---- res/dark/configure-icon.svg | 4 - res/dark/json-icon.svg | 4 - res/dark/settings-icon.svg | 12 -- res/light/build-icon.svg | 8 - res/light/json-icon.svg | 4 - res/light/settings-icon.svg | 12 -- res/product-icons.woff2 | Bin 0 -> 1772 bytes res/product-icons/uE001_build-icon.svg | 1 + .../uE002_clean-configure-icon.svg} | 0 .../uE003_clean-icon.svg} | 0 .../uE004_cmake-view-icon-1.svg} | 0 .../uE005_cmake-view-icon-2.svg} | 0 .../uE006_configure-icon.svg} | 0 .../product-icon-font-generator/.eslintrc.cjs | 159 +++++++++++++++ .../product-icon-font-generator/package.json | 24 +++ .../product-icon-font-generator/src/index.ts | 192 ++++++++++++++++++ .../product-icon-font-generator/tsconfig.json | 12 ++ 21 files changed, 448 insertions(+), 172 deletions(-) delete mode 100644 res/dark/build-icon.svg delete mode 100644 res/dark/clean-configure-icon.svg delete mode 100644 res/dark/clean-icon.svg delete mode 100644 res/dark/configure-icon.svg delete mode 100644 res/dark/json-icon.svg delete mode 100644 res/dark/settings-icon.svg delete mode 100644 res/light/build-icon.svg delete mode 100644 res/light/json-icon.svg delete mode 100644 res/light/settings-icon.svg create mode 100644 res/product-icons.woff2 create mode 100644 res/product-icons/uE001_build-icon.svg rename res/{light/clean-configure-icon.svg => product-icons/uE002_clean-configure-icon.svg} (100%) rename res/{light/clean-icon.svg => product-icons/uE003_clean-icon.svg} (100%) rename res/{cmake-view-icon.svg => product-icons/uE004_cmake-view-icon-1.svg} (100%) rename res/{cmake-view-icon2.svg => product-icons/uE005_cmake-view-icon-2.svg} (100%) rename res/{light/configure-icon.svg => product-icons/uE006_configure-icon.svg} (100%) create mode 100644 tools/product-icon-font-generator/.eslintrc.cjs create mode 100644 tools/product-icon-font-generator/package.json create mode 100644 tools/product-icon-font-generator/src/index.ts create mode 100644 tools/product-icon-font-generator/tsconfig.json diff --git a/package.json b/package.json index 3b71af67b..bb1b2505f 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,50 @@ ], "main": "./dist/main", "contributes": { + "icons": { + "cmake-tools-build": { + "description": "CMake build icon", + "default": { + "fontPath": "./res/product-icons.woff2", + "fontCharacter": "\\E001" + } + }, + "cmake-tools-clean-configure": { + "description": "CMake clean configure icon", + "default": { + "fontPath": "./res/product-icons.woff2", + "fontCharacter": "\\E002" + } + }, + "cmake-tools-clean": { + "description": "CMake clean icon", + "default": { + "fontPath": "./res/product-icons.woff2", + "fontCharacter": "\\E003" + } + }, + "cmake-tools-cmake-view-1": { + "description": "CMake view icon 1", + "default": { + "fontPath": "./res/product-icons.woff2", + "fontCharacter": "\\E004" + } + }, + "cmake-tools-cmake-view-2": { + "description": "CMake view icon 2", + "default": { + "fontPath": "./res/product-icons.woff2", + "fontCharacter": "\\E005" + } + }, + "cmake-tools-configure": { + "description": "CMake configure icon", + "default": { + "fontPath": "./res/product-icons.woff2", + "fontCharacter": "\\E006" + } + } + }, "commands": [ { "command": "cmake.openCMakePresets", @@ -299,18 +343,12 @@ { "command": "cmake.outline.configure", "title": "%cmake-tools.command.cmake.configure.title%", - "icon": { - "dark": "res/dark/configure-icon.svg", - "light": "res/light/configure-icon.svg" - } + "icon": "$(cmake-tools-configure)" }, { "command": "cmake.projectStatus.configure", "title": "%cmake-tools.command.cmake.configure.title%", - "icon": { - "dark": "res/dark/configure-icon.svg", - "light": "res/light/configure-icon.svg" - }, + "icon": "$(cmake-tools-configure)", "when": "cmake:enableFullFeatureSet", "category": "CMake" }, @@ -339,10 +377,7 @@ { "command": "cmake.outline.configureAll", "title": "%cmake-tools.command.cmake.configureAll.title%", - "icon": { - "dark": "res/dark/configure-icon.svg", - "light": "res/light/configure-icon.svg" - } + "icon": "$(cmake-tools-configure)" }, { "command": "cmake.outline.configureAllWithDebugger", @@ -360,28 +395,19 @@ "command": "cmake.outline.build", "title": "%cmake-tools.command.cmake.build.title%", "when": "cmake:enableFullFeatureSet", - "icon": { - "dark": "res/dark/build-icon.svg", - "light": "res/light/build-icon.svg" - } + "icon": "$(cmake-tools-build)" }, { "command": "cmake.projectStatus.build", "title": "%cmake-tools.command.cmake.build.title%", "when": "cmake:enableFullFeatureSet", - "icon": { - "dark": "res/dark/build-icon.svg", - "light": "res/light/build-icon.svg" - } + "icon": "$(cmake-tools-build)" }, { "command": "cmake.outline.buildTarget", "title": "%cmake-tools.command.cmake.build.title%", "when": "cmake:enableFullFeatureSet", - "icon": { - "dark": "res/dark/build-icon.svg", - "light": "res/light/build-icon.svg" - } + "icon": "$(cmake-tools-build)" }, { "command": "cmake.showBuildCommand", @@ -399,29 +425,20 @@ "command": "cmake.outline.buildAll", "title": "%cmake-tools.command.cmake.buildAll.title%", "when": "cmake:enableFullFeatureSet", - "icon": { - "dark": "res/dark/build-icon.svg", - "light": "res/light/build-icon.svg" - } + "icon": "$(cmake-tools-build)" }, { "command": "cmake.compileFile", "title": "%cmake-tools.command.cmake.compileFile.title%", "category": "CMake", "when": "cmake:enableFullFeatureSet", - "icon": { - "dark": "res/dark/build-icon.svg", - "light": "res/light/build-icon.svg" - } + "icon": "$(cmake-tools-build)" }, { "command": "cmake.outline.compileFile", "title": "%cmake-tools.command.cmake.outline.compileFile.title%", "when": "cmake:enableFullFeatureSet", - "icon": { - "dark": "res/dark/build-icon.svg", - "light": "res/light/build-icon.svg" - } + "icon": "$(cmake-tools-build)" }, { "command": "cmake.install", @@ -473,30 +490,21 @@ "title": "%cmake-tools.command.cmake.projectStatus.cleanConfigure.title%", "when": "cmake:enableFullFeatureSet", "category": "CMake", - "icon": { - "dark": "res/dark/clean-configure-icon.svg", - "light": "res/light/clean-configure-icon.svg" - } + "icon": "$(cmake-tools-clean-configure)" }, { "command": "cmake.projectStatus.openSettings", "title": "%cmake-tools.command.cmake.openSettings.title%", "when": "cmake:enableFullFeatureSet", "category": "CMake", - "icon": { - "dark": "res/dark/settings-icon.svg", - "light": "res/light/settings-icon.svg" - } + "icon": "$(settings-gear)" }, { "command": "cmake.projectStatus.openVisibilitySettings", "title": "%cmake-tools.command.cmake.projectStatus.openVisibilitySettings.title%", "when": "cmake:enabelFullFeatureSet", "category": "CMake", - "icon": { - "dark": "res/dark/json-icon.svg", - "light": "res/light/json-icon.svg" - } + "icon": "$(json)" }, { "command": "cmake.cleanConfigureWithDebugger", @@ -539,10 +547,7 @@ "command": "cmake.outline.clean", "when": "cmake:enableFullFeatureSet", "title": "%cmake-tools.command.cmake.clean.title%", - "icon": { - "dark": "res/dark/clean-icon.svg", - "light": "res/light/clean-icon.svg" - } + "icon": "$(cmake-tools-clean)" }, { "command": "cmake.cleanAll", @@ -3620,7 +3625,7 @@ { "id": "cmake-view", "title": "CMake", - "icon": "res/cmake-view-icon2.svg", + "icon": "$(cmake-tools-cmake-view-2)", "when": "cmake:enableFullFeatureSet" } ] @@ -3699,7 +3704,8 @@ "extensionTestsSuccessfulBuild": "yarn run pretest && node ./out/test/extension-tests/successful-build/runTest.js", "extensionTestsSingleRoot": "yarn run pretest && node ./out/test/extension-tests/single-root-UI/runTest.js", "extensionTestsMultiRoot": "yarn run pretest && node ./out/test/extension-tests/multi-root-UI/runTest.js", - "backendTests": "node ./node_modules/mocha/bin/_mocha -u tdd --timeout 999999 --colors -r ts-node/register -r tsconfig-paths/register ./test/backend-unit-tests/**/*.test.ts" + "backendTests": "node ./node_modules/mocha/bin/_mocha -u tdd --timeout 999999 --colors -r ts-node/register -r tsconfig-paths/register ./test/backend-unit-tests/**/*.test.ts", + "build-product-icon-font": "yarn --cwd ./tools/product-icon-font-generator/ install && yarn --cwd ./tools/product-icon-font-generator/ build && node ./tools/product-icon-font-generator/dist/index.js --source-directory ./res/product-icons/ --output-directory ./res/ --woff2" }, "devDependencies": { "@octokit/rest": "^18.1.1", diff --git a/res/dark/build-icon.svg b/res/dark/build-icon.svg deleted file mode 100644 index 2cd8a0c9a..000000000 --- a/res/dark/build-icon.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/res/dark/clean-configure-icon.svg b/res/dark/clean-configure-icon.svg deleted file mode 100644 index b50100191..000000000 --- a/res/dark/clean-configure-icon.svg +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/res/dark/clean-icon.svg b/res/dark/clean-icon.svg deleted file mode 100644 index 5bd9fa9eb..000000000 --- a/res/dark/clean-icon.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - diff --git a/res/dark/configure-icon.svg b/res/dark/configure-icon.svg deleted file mode 100644 index 031cc85f6..000000000 --- a/res/dark/configure-icon.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/res/dark/json-icon.svg b/res/dark/json-icon.svg deleted file mode 100644 index 11e780caf..000000000 --- a/res/dark/json-icon.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/res/dark/settings-icon.svg b/res/dark/settings-icon.svg deleted file mode 100644 index 075129f20..000000000 --- a/res/dark/settings-icon.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/res/light/build-icon.svg b/res/light/build-icon.svg deleted file mode 100644 index 79a8a6333..000000000 --- a/res/light/build-icon.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/res/light/json-icon.svg b/res/light/json-icon.svg deleted file mode 100644 index 79a131272..000000000 --- a/res/light/json-icon.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/res/light/settings-icon.svg b/res/light/settings-icon.svg deleted file mode 100644 index 2f58e5402..000000000 --- a/res/light/settings-icon.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/res/product-icons.woff2 b/res/product-icons.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..6af38d6d30cfec17a9ae04afc86d8bb61804a1d4 GIT binary patch literal 1772 zcmV=hqRpZ{?iWF0kYoB0vq+hP6H7@bybmFJz7b45ht?=R_6UNfP=~X z#Jp|`4Zv$){I-$-Hb)OpsCuF=4)>0Mk+B;AMy;v7dK2S87b%{TdnltKM9Hd- zEjngfTcI-bBrLlMUuSECs<-u@;nk}hT%-TMlP-b)tF{G7lV+8Tz<10*ia{ie94!cn z%9xQl2Dq<6Xa)I&nS@-*wE2Nl9b zJe3U+pv;P0ha1kr%Lgik7!-O$9%J3GA|B+@e2^G@0Xw1}Z^YUFI#5CVCWXm6nK55Q z9<4j7HLG;oGZ5q!yEilpE$N|SKnVIiNc{gFFm1vRlauX(P>+lfLB(WAlMK_Rz<;5> z9mA4R@(S!+qTB*}B4Xk^GQ844f)Z@9a)e4}FtI=qacli>q|1>nl`p_dvg5{+o+03i z#72^uDIE&3{uQtlDvT&>2gn|%ncE^7@PjrSpaUo9A`E&+f<97UfIJwY0G40}d*K56 z5d{a}1_u!Uhu{N;5dlXK14j`D$Ke4dkpZXR1*ee)XAlBs5d;^I0GD9{SC9o)-E#OA z6dWyvAXG>QLWdSd5C*ga1Yv@fh;mo}6s-+b0gNCYp-dq4ZGsw#=&I?FW-Uzivqb7rkEBXg z=@PmQ03m5hr3z&a(fxe>gF>DMUnx^#Q&UT0Lt0}?*ETKmu1->~R9Rx=KLFB1sb^i)ZOFTO>TaDw`iBgw7DOWEcIbV&4ALq1p{~O2f##eh zoXTW2>bAqe*I!S)x@6<(f~<<0tFyOUS@7kRRI7^dtE;jpZ!K)0t-;e42HrDOH2Fpr zp6l~?)21oX8fKrZ)THS4t>ip^Rr<>9{%+f^o8*yH*c^o$vop7Z)H(8~&v`IxdDKh2 z{<1PaH{`x>I?qhc7`#}JBCTTTTH(;k?HwzsCBisECo=1-*t7xhk_k_LUp3mXN;`;U<2rrq@hHO@5oCMV{?z$q`Su!>uy0>pT|V(| z;gY4rBDtdQZ(uf=d#cc8?#Y1z{fd?>FBQrZ>5mmF+{?E;>}0-9`d)c`cB5Z^cI3tE z)%N%~ZlY2NV;_)XWplXUSk9~3SpG=30H~*;(f?lz@Yf-p8x#z4LYT{(g0S zO!~*j_k<4dP1ju!Rufs2SE+>DEQe|W@%iMUX0<63T z{AtCxy_rj#aF889(H#L*J>3tY*<_%zX~N(zfmO}&<~Ba(Igxk@5w*ggaC!t))C;27 zyn!z08w^qZVYMY>czK&*7&bv5yp5w814pn}k90OOBP46@tZhbuXdoCSH``gaQGzfM z7>anv4nWbaOQBQ?wF0rgVuC3$n+c@a8&Ty1J*C$4#MTkqN&-hLz)C>yY&ew0aU22@ z)kAb_re+L*(!fJhGqj2k8KQFwbu_i9q(sGZuM7&|qYfCba$jVplfqLeEokudsl`*5 z>+wWtR+Q|;ww;VnOoC%IQmxXpL|aFwYC_Mt<#m~a30CqR7Xv8CimK^`Y1xkJ`5-U^ z3WFn%C^QC(!xM-kGKET`GeU-`v6GwRS2vc|uuV7?ZK7ADyrdYbY&Nxgb=O>bmD53X z8DeTz_c;#(v2KtQQ#MrQyXq+=WO*N&GAi11(N!N&(p$TD${m`3D|Wb&yc \ No newline at end of file diff --git a/res/light/clean-configure-icon.svg b/res/product-icons/uE002_clean-configure-icon.svg similarity index 100% rename from res/light/clean-configure-icon.svg rename to res/product-icons/uE002_clean-configure-icon.svg diff --git a/res/light/clean-icon.svg b/res/product-icons/uE003_clean-icon.svg similarity index 100% rename from res/light/clean-icon.svg rename to res/product-icons/uE003_clean-icon.svg diff --git a/res/cmake-view-icon.svg b/res/product-icons/uE004_cmake-view-icon-1.svg similarity index 100% rename from res/cmake-view-icon.svg rename to res/product-icons/uE004_cmake-view-icon-1.svg diff --git a/res/cmake-view-icon2.svg b/res/product-icons/uE005_cmake-view-icon-2.svg similarity index 100% rename from res/cmake-view-icon2.svg rename to res/product-icons/uE005_cmake-view-icon-2.svg diff --git a/res/light/configure-icon.svg b/res/product-icons/uE006_configure-icon.svg similarity index 100% rename from res/light/configure-icon.svg rename to res/product-icons/uE006_configure-icon.svg diff --git a/tools/product-icon-font-generator/.eslintrc.cjs b/tools/product-icon-font-generator/.eslintrc.cjs new file mode 100644 index 000000000..795d0b79e --- /dev/null +++ b/tools/product-icon-font-generator/.eslintrc.cjs @@ -0,0 +1,159 @@ +module.exports = { + "env": { + "browser": true, + "es6": true, + "node": true + }, + "parser": "@typescript-eslint/parser", + "parserOptions": { + "project": "tsconfig.json", + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint", + "@typescript-eslint/tslint", + "eslint-plugin-jsdoc", + "@typescript-eslint/eslint-plugin-tslint", + "eslint-plugin-import", + ], + "rules": { + "@typescript-eslint/adjacent-overload-signatures": "error", + "@typescript-eslint/array-type": "error", + "camelcase": "off", + "@typescript-eslint/naming-convention": [ + "error", + { + "selector": "typeLike", + "format": ["PascalCase"] + } + ], + "@typescript-eslint/indent": "error", + "@typescript-eslint/member-delimiter-style": [ + "error", + { + "multiline": { + "delimiter": "semi", + "requireLast": true + }, + "singleline": { + "delimiter": "semi", + "requireLast": false + } + } + ], + "@typescript-eslint/no-for-in-array": "error", + "@typescript-eslint/no-misused-new": "error", + "@typescript-eslint/no-misused-promises": "error", + //"@typescript-eslint/no-namespace": "error", + //"@typescript-eslint/no-non-null-assertion": "error", + "@typescript-eslint/no-extra-non-null-assertion": "error", + "@typescript-eslint/no-this-alias": "error", + "@typescript-eslint/no-unnecessary-qualifier": "error", + "@typescript-eslint/no-unnecessary-type-arguments": "error", + //"@typescript-eslint/no-var-requires": "error", + "@typescript-eslint/prefer-function-type": "error", + "@typescript-eslint/prefer-namespace-keyword": "error", + "@typescript-eslint/semi": "error", + "@typescript-eslint/triple-slash-reference": "error", + "@typescript-eslint/type-annotation-spacing": "error", + //"@typescript-eslint/unified-signatures": "error", + "@typescript-eslint/no-floating-promises": "error", + "@typescript-eslint/await-thenable": "error", + "arrow-body-style": "error", + "brace-style": "error", + "comma-dangle": "error", + "constructor-super": "error", + "curly": "error", + "eol-last": "error", + "eqeqeq": [ + "error", + "always" + ], + //"import/no-default-export": "error", + "import/no-unassigned-import": "error", + "jsdoc/no-types": "error", + "new-parens": "error", + "no-bitwise": "error", + "no-caller": "error", + "no-cond-assign": "error", + //"no-debugger": "error", + "no-duplicate-case": "error", + //"no-duplicate-imports": "error", + "no-eval": "error", + "no-fallthrough": "error", + //"no-invalid-this": "error", + "no-irregular-whitespace": "error", + "no-multiple-empty-lines": ["error", { "max": 1, "maxEOF": 1, "maxBOF": 0 }], + "no-new-wrappers": "error", + "no-redeclare": "error", + "no-return-await": "error", + "no-sequences": "error", + "no-sparse-arrays": "error", + "no-trailing-spaces": "error", + "no-undef-init": "error", + "no-unsafe-finally": "error", + "no-unused-expressions": "off", + "no-unused-labels": "error", + "no-var": "error", + "one-var": [ + "error", + "never" + ], + "prefer-const": "error", + "prefer-object-spread": "error", + "space-in-parens": [ + "error", + "never" + ], + /*"spaced-comment": [ + "error", + "always" + ],*/ + "use-isnan": "error", + "valid-typeof": "error", + "yoda": "error", + "@typescript-eslint/tslint/config": [ + "error", + { + "rules": { + "encoding": true, + /*"file-header": [ + true, + ".*" + ],*/ + "import-spacing": true, + "match-default-export-name": true, + "no-boolean-literal-compare": true, + "no-mergeable-namespace": true, + "no-reference-import": true, + "no-unnecessary-callback-wrapper": false, + "number-literal-format": true, + "one-line": [ + true, + "check-catch", + "check-finally", + "check-else", + "check-open-brace", + "check-whitespace" + ], + "prefer-method-signature": true, + "prefer-while": true, + /*"typedef": [ + true, + "variable-declaration", + "call-signature", + "variable-declaration-ignore-function" + ],*/ + "whitespace": [ + true, + "check-branch", + "check-operator", + "check-separator", + "check-preblock", + "check-type" + ] + } + } + ] + } +}; diff --git a/tools/product-icon-font-generator/package.json b/tools/product-icon-font-generator/package.json new file mode 100644 index 000000000..23e0a2be2 --- /dev/null +++ b/tools/product-icon-font-generator/package.json @@ -0,0 +1,24 @@ +{ + "name": "product-icon-font-generator", + "version": "0.1.0", + "private": true, + "type": "module", + "scripts": { + "build": "tsc -p ./", + "clean": "rimraf ./dist", + "lint": "eslint src --ext ts --max-warnings 0" + }, + "dependencies": { + "fontagon": "^1.1.1", + "ttf2woff2": "^6" + }, + "devDependencies": { + "@types/fontagon": "^1.1.4", + "@types/node": "^20.13", + "commander": "^12.0.0", + "eslint": "^8.25.0", + "rimraf": "^3.0.2", + "ts-node": "^10.9.1", + "typescript": "^5.1.0" + } +} diff --git a/tools/product-icon-font-generator/src/index.ts b/tools/product-icon-font-generator/src/index.ts new file mode 100644 index 000000000..8622a86f1 --- /dev/null +++ b/tools/product-icon-font-generator/src/index.ts @@ -0,0 +1,192 @@ +import * as path from "path"; +import * as fs from "fs"; + +import * as commander from "commander"; +import Fontagon from "fontagon"; + +type Optional = T | undefined; + +/** + * Supported font formats to output. + * + * @enum {number} + */ +enum FontFormat { + WOFF, + WOFF2, +} + +/** + * Struct to store icon file metadata. + */ +class SvgIcon { + public fp: string; + public glyphCode: number; + public name: string; + + constructor(args: {fp: string; glyph_code: number; name: Optional}) { + this.fp = args.fp; + this.glyphCode = args.glyph_code; + this.name = args.name || ''; + } +} + +/** + * Generator class for generating webfonts. + */ +class WebfontGenerator { + private readonly _FILE_MATCHER = new RegExp("^u(?[0-9a-f]{4})[-_]?(?.*)\\.svg$", "i"); + + private _svgIcons: SvgIcon[]; + private _enabledFormats: Set; + + constructor() { + this._svgIcons = []; + this._enabledFormats = new Set(); + } + + /** + * Enables a font output format. + * + * @public + * @param format Format to enable. + */ + public enableFormat(format: FontFormat) { + this._enabledFormats.add(format); + } + + /** + * Searches and adds all icons files recursively from a given base directory. + * + * @public + * @param baseDir Base directory to recursively process. + */ + public addFromDirectory(baseDir: string) { + baseDir = path.resolve(baseDir); + if (!fs.statSync(baseDir).isDirectory()) { + return; + } + + for (let fp of fs.readdirSync(baseDir)) { + // Full path, as well as replace backwards slashes as webfont requires forward slashes. + fp = path.join(baseDir, fp).replace(/\\/g, '/'); + const parsed_fp = path.parse(fp); + + const match = this._FILE_MATCHER.exec(parsed_fp.base); + if (match?.groups && fs.statSync(fp).isFile()) { + this._svgIcons.push(new SvgIcon({ + fp: fp, + glyph_code: Number.parseInt(`0x${match.groups['code']}`), + name: parsed_fp.name + })); + console.log(`Added icon: '${fp}'`); + console.log(Number.parseInt(`0x${match.groups['code']}`)); + // Assume a directory (checked in begin of function when recursing). + } else { + this.addFromDirectory(fp); + } + } + } + + /** + * Generates and outputs the font files from the added icons. + * + * @public + * @async + * @param outputDirectory Directory to output the font files. + * @param name Font name. + */ + public async generate(outputDirectory: string, name: Optional = undefined): Promise { + if (!this._enabledFormats.size) { + console.warn("No enabled font formats to output; nothing to generate."); + return; + } + + outputDirectory = path.resolve(outputDirectory); + if (!fs.existsSync(outputDirectory)) { + throw Error(`Output directory does not exist '${outputDirectory}'`); + } + + // Fontagon automatically cleans/removes directories, so make a temporary directory and move the files over + // after generation to the actual output directory. + const tmp_directory = path.join(outputDirectory, 'tmp'); + !fs.existsSync(tmp_directory) && fs.mkdirSync(tmp_directory); + + // Enable formats to output, alongside any optional format options. Furthmore, Fontagon also outputs intermediate + // font formats, so we'll keep track of the files by extension that we want to keep. + const format_options: Fontagon.FormatOptions = {}; + const extensions: string[] = []; + for (const format of this._enabledFormats) { + switch (format) { + case FontFormat.WOFF: + format_options['woff'] = {}; + extensions.push('.woff'); + break; + case FontFormat.WOFF2: + format_options['woff2'] = {}; + extensions.push('.woff2'); + break; + default: + throw Error(`Unsupported font format '${FontFormat[format]}'.`); + } + }; + + await Fontagon({ + files: this._svgIcons.map((svg_icon) => svg_icon.fp), + codepoints: this._svgIcons.reduce((a, svg_icon) => ({ ...a, [svg_icon.name]: svg_icon.glyphCode }), {}), + dist: tmp_directory, + fontName: name || path.basename(opts.sourceDirectory), + style: undefined, + formatOptions: { ...format_options, + // The SVG intermediate format has all the transformative options we can set. + svg: { + fontHeight: 1000, + normalize: false + } + } + }); + + // Move over all files from the temporary directory + for (const fp of fs.readdirSync(tmp_directory)) { + if (!extensions.includes(path.parse(fp).ext)) { + continue; + } + fs.renameSync( + path.resolve(tmp_directory, fp), + path.join(outputDirectory, path.basename(fp))); + } + fs.existsSync(tmp_directory) && fs.rmSync(tmp_directory, { recursive: true }); + } +} + +commander.program + .name("product-icon-generator") + .description("Takes SVG icons and generates it into a product icon font.") + // I/O arguments. + .requiredOption("--source-directory ", "The root directory where to recursively import icons from. Filenames must start with a hexadecimal glyph codepoint (e.g. '0xE001.svg')") + .option("-o, --output-directory ", "Directory where to output the webfont file. Defaults to the source directory if not set.") + .option("--name ", "(File)name of the font. Defaults to the directory name if this option is not set.") + // Font format generation arguments. Each format should be enabled explicitly by the user. + .option("--woff", "Enables WOFF font generation.") + .option("--woff2", "Enables WOFF2 font generation.") + .parse(); +const opts = commander.program.opts(); + +try { + const generator = new WebfontGenerator(); + + const register_format = (opt: boolean, format: FontFormat) => { + opt && generator.enableFormat(format); + }; + register_format(opts.woff , FontFormat.WOFF); + register_format(opts.woff2, FontFormat.WOFF2); + + generator.addFromDirectory(opts.sourceDirectory); + + await generator.generate( + opts.outputDirectory || opts.sourceDirectory, + opts.name + ); +} catch (e) { + console.error('Font creation failed.', e); +} diff --git a/tools/product-icon-font-generator/tsconfig.json b/tools/product-icon-font-generator/tsconfig.json new file mode 100644 index 000000000..c2a6eb6e8 --- /dev/null +++ b/tools/product-icon-font-generator/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "strict": true, + "module": "es2022", + "target": "es2022", + "moduleResolution": "Node", + "forceConsistentCasingInFileNames": true, + "esModuleInterop": true + } +} From bab2895173c56d7c815febf52968b5d58e8881dd Mon Sep 17 00:00:00 2001 From: "CSIGS@microsoft.com" Date: Mon, 21 Oct 2024 09:33:49 -0700 Subject: [PATCH 3/3] Localization - Translated Strings (#4121) --- i18n/chs/package.i18n.json | 1 + i18n/cht/package.i18n.json | 1 + i18n/csy/package.i18n.json | 1 + i18n/deu/package.i18n.json | 1 + i18n/esn/package.i18n.json | 1 + i18n/fra/package.i18n.json | 1 + i18n/ita/package.i18n.json | 1 + i18n/jpn/package.i18n.json | 1 + i18n/kor/package.i18n.json | 1 + i18n/plk/package.i18n.json | 1 + i18n/ptb/package.i18n.json | 1 + i18n/rus/package.i18n.json | 1 + i18n/trk/package.i18n.json | 1 + 13 files changed, 13 insertions(+) diff --git a/i18n/chs/package.i18n.json b/i18n/chs/package.i18n.json index 7cf328f24..5e8463cb6 100644 --- a/i18n/chs/package.i18n.json +++ b/i18n/chs/package.i18n.json @@ -165,6 +165,7 @@ "cmake-tools.configuration.cmake.outputLogEncoding.description": "来自外部命令的输出的编码(例如 cmake -- build)。", "cmake-tools.configuration.cmake.enableTraceLogging.description": "对文件和控制台启用跟踪日志记录(噪音很大)。", "cmake-tools.configuration.cmake.autoSelectActiveFolder.description": "自动选择活动文件夹。", + "cmake-tools.configuration.cmake.defaultActiveFolder.description": "设置默认活动文件夹(仅在禁用 cmake.autoSelectActiveFolder 时有效)。", "cmake-tools.configuration.cmake.touchbar.advanced.description": "配置扩展如何在 MacBook 触摸栏上显示按钮的高级设置。", "cmake-tools.configuration.cmake.touchbar.visibility.description": "配置扩展在 MacBook 触控栏上显示按钮的方式。", "cmake-tools.configuration.cmake.touchbar.visibility.default.description": "在支持的系统上显示触控栏按钮。", diff --git a/i18n/cht/package.i18n.json b/i18n/cht/package.i18n.json index b51a24eda..c925ae2b3 100644 --- a/i18n/cht/package.i18n.json +++ b/i18n/cht/package.i18n.json @@ -165,6 +165,7 @@ "cmake-tools.configuration.cmake.outputLogEncoding.description": "外部命令輸出的編譯 (例如 cmake -- build)。", "cmake-tools.configuration.cmake.enableTraceLogging.description": "為檔案及主控台啟用追蹤記錄 (雜訊非常多)。", "cmake-tools.configuration.cmake.autoSelectActiveFolder.description": "自動選取使用中的資料夾。", + "cmake-tools.configuration.cmake.defaultActiveFolder.description": "設定預設作用中資料夾 (只有在 cmake.autoSelectActiveFolder 停用時才有效)。", "cmake-tools.configuration.cmake.touchbar.advanced.description": "設定延伸模組在 MacBook 觸控列上顯示按鈕之進階設定的方式。", "cmake-tools.configuration.cmake.touchbar.visibility.description": "設定延伸模組在 MacBook 觸控列上顯示按鈕的方式。", "cmake-tools.configuration.cmake.touchbar.visibility.default.description": "在支援的系統上顯示觸控列按鈕。", diff --git a/i18n/csy/package.i18n.json b/i18n/csy/package.i18n.json index 92ab01bed..5a5a12175 100644 --- a/i18n/csy/package.i18n.json +++ b/i18n/csy/package.i18n.json @@ -165,6 +165,7 @@ "cmake-tools.configuration.cmake.outputLogEncoding.description": "Kódování výstupu z externích příkazů (např. cmake -- build)", "cmake-tools.configuration.cmake.enableTraceLogging.description": "Povolit protokolování trasování do souboru a konzoly (velmi vysoké objemy dat)", "cmake-tools.configuration.cmake.autoSelectActiveFolder.description": "Vybrat aktivní složku automaticky", + "cmake-tools.configuration.cmake.defaultActiveFolder.description": "Nastavte výchozí aktivní složku (funguje jenom v případě, že je zakázané nastavení cmake.autoSelectActiveFolder).", "cmake-tools.configuration.cmake.touchbar.advanced.description": "Nakonfiguruje upřesňující nastavení pro způsob, jakým rozšíření zobrazuje tlačítka na Touch Baru MacBooku.", "cmake-tools.configuration.cmake.touchbar.visibility.description": "Nakonfiguruje, jak rozšíření zobrazuje tlačítka na Touch Baru na MacBooku.", "cmake-tools.configuration.cmake.touchbar.visibility.default.description": "Umožňuje zobrazit na podporovaných systémech tlačítka Touch Baru.", diff --git a/i18n/deu/package.i18n.json b/i18n/deu/package.i18n.json index 7dbcd757b..d13e08163 100644 --- a/i18n/deu/package.i18n.json +++ b/i18n/deu/package.i18n.json @@ -165,6 +165,7 @@ "cmake-tools.configuration.cmake.outputLogEncoding.description": "Codierung der Ausgabe von externen Befehlen (z. B.: cmake --build).", "cmake-tools.configuration.cmake.enableTraceLogging.description": "Hiermit wird die Ablaufverfolgungsprotokollierung in Datei und Konsole aktiviert (große Datenmenge).", "cmake-tools.configuration.cmake.autoSelectActiveFolder.description": "Hiermit wird der aktive Ordner automatisch ausgewählt.", + "cmake-tools.configuration.cmake.defaultActiveFolder.description": "Legen Sie den standardmäßigen aktiven Ordner fest (funktioniert nur, wenn cmake.autoSelectActiveFolder deaktiviert ist).", "cmake-tools.configuration.cmake.touchbar.advanced.description": "Hiermit werden erweiterte Einstellungen konfiguriert, wie die Erweiterung die Schaltflächen auf einer MacBook Touch Bar anzeigt.", "cmake-tools.configuration.cmake.touchbar.visibility.description": "Hiermit wird konfiguriert, wie die Erweiterung die Schaltflächen auf einer MacBook Touch Bar anzeigt.", "cmake-tools.configuration.cmake.touchbar.visibility.default.description": "Hiermit werden die Touch Bar-Schaltflächen auf unterstützten Systemen angezeigt.", diff --git a/i18n/esn/package.i18n.json b/i18n/esn/package.i18n.json index 2fc251397..9342a4fee 100644 --- a/i18n/esn/package.i18n.json +++ b/i18n/esn/package.i18n.json @@ -165,6 +165,7 @@ "cmake-tools.configuration.cmake.outputLogEncoding.description": "Codificación de la salida de los comandos externos (por ejemplo, cmake -- build).", "cmake-tools.configuration.cmake.enableTraceLogging.description": "Habilita el registro de seguimiento para el archivo y la consola (con mucho ruido).", "cmake-tools.configuration.cmake.autoSelectActiveFolder.description": "Seleccione la carpeta activa de forma automática.", + "cmake-tools.configuration.cmake.defaultActiveFolder.description": "Establezca la carpeta activa predeterminada (solo funciona cuando cmake.autoSelectActiveFolder está deshabilitado).", "cmake-tools.configuration.cmake.touchbar.advanced.description": "Configura ajustes avanzados sobre cómo la extensión muestra los botones en la Touch Bar de un MacBook.", "cmake-tools.configuration.cmake.touchbar.visibility.description": "Configura cómo la extensión muestra los botones en la Touch Bar de un MacBook.", "cmake-tools.configuration.cmake.touchbar.visibility.default.description": "Muestra los botones de la barra táctil en los sistemas compatibles.", diff --git a/i18n/fra/package.i18n.json b/i18n/fra/package.i18n.json index 8508aee82..a47ba8ced 100644 --- a/i18n/fra/package.i18n.json +++ b/i18n/fra/package.i18n.json @@ -165,6 +165,7 @@ "cmake-tools.configuration.cmake.outputLogEncoding.description": "Encodage de la sortie à partir de commandes externes (par exemple cmake -- build).", "cmake-tools.configuration.cmake.enableTraceLogging.description": "Active la journalisation des traces dans le fichier et la console (très bruyant).", "cmake-tools.configuration.cmake.autoSelectActiveFolder.description": "Sélectionne le dossier actif automatiquement.", + "cmake-tools.configuration.cmake.defaultActiveFolder.description": "Définir le dossier actif par défaut (fonctionne uniquement lorsque cmake.autoSelectActiveFolder est désactivé).", "cmake-tools.configuration.cmake.touchbar.advanced.description": "Configure les paramètres avancés pour la façon dont l'extension affiche les boutons sur une barre tactile MacBook.", "cmake-tools.configuration.cmake.touchbar.visibility.description": "Configure la façon dont l'extension affiche les boutons sur une barre tactile MacBook.", "cmake-tools.configuration.cmake.touchbar.visibility.default.description": "Affiche les boutons de la Touch Bar sur les systèmes pris en charge.", diff --git a/i18n/ita/package.i18n.json b/i18n/ita/package.i18n.json index 4f03f268c..120774282 100644 --- a/i18n/ita/package.i18n.json +++ b/i18n/ita/package.i18n.json @@ -165,6 +165,7 @@ "cmake-tools.configuration.cmake.outputLogEncoding.description": "Codifica dell'output di comandi esterni (ad esempio cmake -- build).", "cmake-tools.configuration.cmake.enableTraceLogging.description": "Abilita la registrazione traccia in file e console (molto disturbata).", "cmake-tools.configuration.cmake.autoSelectActiveFolder.description": "Seleziona automaticamente la cartella attiva.", + "cmake-tools.configuration.cmake.defaultActiveFolder.description": "Impostare la cartella attiva predefinita (funziona solo quando cmake.autoSelectActiveFolder è disabilitato).", "cmake-tools.configuration.cmake.touchbar.advanced.description": "Configura le impostazioni avanzate per la modalità di visualizzazione dei pulsanti dell'estensione in una touch bar per MacBook.", "cmake-tools.configuration.cmake.touchbar.visibility.description": "Configura il modo in cui l'estensione visualizza i pulsanti su una Touch Bar del MacBook.", "cmake-tools.configuration.cmake.touchbar.visibility.default.description": "Mostra i pulsanti della Touch Bar sui sistemi supportati.", diff --git a/i18n/jpn/package.i18n.json b/i18n/jpn/package.i18n.json index c7b9fdec8..f125c381b 100644 --- a/i18n/jpn/package.i18n.json +++ b/i18n/jpn/package.i18n.json @@ -165,6 +165,7 @@ "cmake-tools.configuration.cmake.outputLogEncoding.description": "外部コマンドからの出力のエンコードです (例: cmake -- build)。", "cmake-tools.configuration.cmake.enableTraceLogging.description": "ファイルおよびコンソールへのトレース ログを有効にします (非常に煩雑になります)。", "cmake-tools.configuration.cmake.autoSelectActiveFolder.description": "アクティブなフォルダーを自動的に選択します。", + "cmake-tools.configuration.cmake.defaultActiveFolder.description": "既定のアクティブ フォルダーを設定します (cmake.autoSelectActiveFolder が無効である場合にのみ機能します)。", "cmake-tools.configuration.cmake.touchbar.advanced.description": "拡張機能によってボタンが MacBook の Touch Bar にどのように表示されるか詳細設定を構成します。", "cmake-tools.configuration.cmake.touchbar.visibility.description": "拡張機能によってボタンが MacBook の Touch Bar にどのように表示されるかを構成します。", "cmake-tools.configuration.cmake.touchbar.visibility.default.description": "サポートされているシステムで Touch Bar ボタンを表示します。", diff --git a/i18n/kor/package.i18n.json b/i18n/kor/package.i18n.json index 6a0950922..25529ad7e 100644 --- a/i18n/kor/package.i18n.json +++ b/i18n/kor/package.i18n.json @@ -165,6 +165,7 @@ "cmake-tools.configuration.cmake.outputLogEncoding.description": "외부 명령의 출력 인코딩입니다(예: cmake -- build).", "cmake-tools.configuration.cmake.enableTraceLogging.description": "파일 및 콘솔에 대한 추적 로깅을 사용합니다(매우 불안정함).", "cmake-tools.configuration.cmake.autoSelectActiveFolder.description": "활성 폴더를 자동으로 선택합니다.", + "cmake-tools.configuration.cmake.defaultActiveFolder.description": "기본 활성 폴더를 설정합니다(cmake.autoSelectActiveFolder를 사용하지 않도록 설정한 경우에만 작동).", "cmake-tools.configuration.cmake.touchbar.advanced.description": "확장에서 MacBook 터치 바에 단추를 표시하는 방법에 대한 고급 설정을 구성합니다.", "cmake-tools.configuration.cmake.touchbar.visibility.description": "확장이 MacBook Touch Bar에 단추를 표시하는 방식을 구성합니다.", "cmake-tools.configuration.cmake.touchbar.visibility.default.description": "지원되는 시스템에 Touch Bar 단추를 표시합니다.", diff --git a/i18n/plk/package.i18n.json b/i18n/plk/package.i18n.json index 000c55338..558931cf3 100644 --- a/i18n/plk/package.i18n.json +++ b/i18n/plk/package.i18n.json @@ -165,6 +165,7 @@ "cmake-tools.configuration.cmake.outputLogEncoding.description": "Kodowanie danych wyjściowych z poleceń zewnętrznych (np. cmake --build).", "cmake-tools.configuration.cmake.enableTraceLogging.description": "Włącz rejestrowanie śledzenia w pliku i na konsoli (bardzo dużo danych).", "cmake-tools.configuration.cmake.autoSelectActiveFolder.description": "Wybierz aktywny folder automatycznie.", + "cmake-tools.configuration.cmake.defaultActiveFolder.description": "Ustaw domyślny aktywny folder (działa tylko wtedy, gdy właściwość cmake.autoSelectActiveFolder jest wyłączona).", "cmake-tools.configuration.cmake.touchbar.advanced.description": "Konfiguruje zaawansowane ustawienia wyświetlania przez rozszerzenie przycisków na pasku Touch Bar komputera MacBook.", "cmake-tools.configuration.cmake.touchbar.visibility.description": "Konfiguruje sposób wyświetlania przez rozszerzenie przycisków na pasku Touch Bar komputera MacBook.", "cmake-tools.configuration.cmake.touchbar.visibility.default.description": "Pokaż przyciski paska Touch Bar w obsługiwanych systemach.", diff --git a/i18n/ptb/package.i18n.json b/i18n/ptb/package.i18n.json index 48ddbdd81..a03cfca8e 100644 --- a/i18n/ptb/package.i18n.json +++ b/i18n/ptb/package.i18n.json @@ -165,6 +165,7 @@ "cmake-tools.configuration.cmake.outputLogEncoding.description": "A codificação da saída de comandos externos (ex.: cmake -- build).", "cmake-tools.configuration.cmake.enableTraceLogging.description": "Habilitar o log de rastreamento para arquivo e console (muito ruído).", "cmake-tools.configuration.cmake.autoSelectActiveFolder.description": "Selecionar a pasta ativa automaticamente.", + "cmake-tools.configuration.cmake.defaultActiveFolder.description": "Defina a pasta ativa padrão (só funciona quando cmake.autoSelectActiveFolder está desabilitado).", "cmake-tools.configuration.cmake.touchbar.advanced.description": "Define configurações avançadas de como a extensão exibe botões em uma Touch Bar do MacBook.", "cmake-tools.configuration.cmake.touchbar.visibility.description": "Configura como a extensão exibe os botões em uma Touch Bar do MacBook.", "cmake-tools.configuration.cmake.touchbar.visibility.default.description": "Mostrar os botões da Touch Bar nos sistemas com suporte.", diff --git a/i18n/rus/package.i18n.json b/i18n/rus/package.i18n.json index c8e6c8e0f..1256cd654 100644 --- a/i18n/rus/package.i18n.json +++ b/i18n/rus/package.i18n.json @@ -165,6 +165,7 @@ "cmake-tools.configuration.cmake.outputLogEncoding.description": "Кодирование выходных данных из внешних команд (например, cmake --build).", "cmake-tools.configuration.cmake.enableTraceLogging.description": "Включение ведения журнала трассировки в файле и в консоли (большое число сообщений).", "cmake-tools.configuration.cmake.autoSelectActiveFolder.description": "Автоматический выбор активной папки.", + "cmake-tools.configuration.cmake.defaultActiveFolder.description": "Настройте активную папку по умолчанию (работает, только если параметр cmake.autoSelectActiveFolder отключен).", "cmake-tools.configuration.cmake.touchbar.advanced.description": "Настраивает дополнительные параметры того, как расширение отображает кнопки в панели Touch Bar на MacBook.", "cmake-tools.configuration.cmake.touchbar.visibility.description": "Настраивает отображение кнопок расширения в панели Touch Bar на MacBook.", "cmake-tools.configuration.cmake.touchbar.visibility.default.description": "Отображение кнопок панели Touch Bar на поддерживаемых системах.", diff --git a/i18n/trk/package.i18n.json b/i18n/trk/package.i18n.json index cb91e74f6..f248169fc 100644 --- a/i18n/trk/package.i18n.json +++ b/i18n/trk/package.i18n.json @@ -165,6 +165,7 @@ "cmake-tools.configuration.cmake.outputLogEncoding.description": "Dış komutlardan (ör. cmake -- build) gelen çıkışın kodlaması.", "cmake-tools.configuration.cmake.enableTraceLogging.description": "Dosya ve konsolda izleme günlüğünü etkinleştirin (çok gürültülü).", "cmake-tools.configuration.cmake.autoSelectActiveFolder.description": "Etkin klasörü otomatik olarak seçin.", + "cmake-tools.configuration.cmake.defaultActiveFolder.description": "Varsayılan etkin klasörü ayarla (yalnızca cmake.autoSelectActiveFolder devre dışı bırakıldığında çalışır).", "cmake-tools.configuration.cmake.touchbar.advanced.description": "Uzantının, düğmeleri MacBook Touch Bar'da nasıl görüntüleyeceğinin gelişmiş yapılandırmalarını ayarlar.", "cmake-tools.configuration.cmake.touchbar.visibility.description": "Uzantının, düğmeleri MacBook Touch Bar'da nasıl görüntüleyeceğini yapılandırır.", "cmake-tools.configuration.cmake.touchbar.visibility.default.description": "Desteklenen sistemlerde Touch Bar düğmelerini göster.",