From e57637aab10b14ed2857438985cdc8fdf96cbccb Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Mon, 19 May 2025 02:38:29 -0700 Subject: [PATCH] Make builds of the editor and the website serve their own local fonts (#2186) * WIP * Done? * Install fonts in CI * Use absolute path so minified inlined CSS works * Fix Bezier-rs demo fonts? * Use opsz * Revert removal of text balancer * Pull in the text balancer from our static host --- .github/workflows/website.yml | 7 +- Cargo.lock | 6 +- .../document/overlays/utility_types.rs | 2 +- frontend/README.md | 2 +- frontend/index.html | 123 +- frontend/package-lock.json | 28 +- frontend/package.json | 2 + frontend/src/main.ts | 9 +- website/.eslintrc.js | 9 +- website/.gitignore | 2 + website/config_prod.toml | 17 - website/content/_index.md | 6 +- website/content/about.md | 9 +- website/content/features.md | 16 +- website/install-fonts.js | 194 +++ website/other/bezier-rs-demos/index.html | 4 +- .../other/bezier-rs-demos/public/style.css | 2 +- website/other/build.sh | 1 + website/package-lock.json | 1507 ++++++++++------- website/package.json | 12 +- website/sass/base.scss | 19 +- website/sass/component/code-snippet.scss | 2 +- website/sass/component/feature-box.scss | 2 +- website/sass/layout/balance-text.scss | 22 - website/sass/page/about.scss | 14 +- website/templates/article.html | 2 +- website/templates/base.html | 15 +- website/templates/macros/replacements.html | 26 + 28 files changed, 1305 insertions(+), 755 deletions(-) delete mode 100644 website/config_prod.toml create mode 100644 website/install-fonts.js delete mode 100644 website/sass/layout/balance-text.scss diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml index 03eda92e..c137b579 100644 --- a/.github/workflows/website.yml +++ b/.github/workflows/website.yml @@ -13,7 +13,7 @@ on: - website/** env: CARGO_TERM_COLOR: always - INDEX_HTML_HEAD_INCLUSION: + INDEX_HTML_HEAD_INCLUSION: jobs: build: @@ -30,7 +30,7 @@ jobs: - name: πŸ•Έ Install Zola uses: taiki-e/install-action@v2 with: - tool: zola@0.19.1 + tool: zola@0.20.0 - name: βœ‚ Replace template in of index.html run: | @@ -42,7 +42,8 @@ jobs: MODE: prod run: | cd website - zola --config config_prod.toml build + npm run install-fonts + zola --config config.toml build --minify - name: πŸ” Check if `website/other` directory changed uses: dorny/paths-filter@v3 diff --git a/Cargo.lock b/Cargo.lock index 42c2c486..0c347cf8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3362,7 +3362,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.48.5", ] [[package]] @@ -6635,9 +6635,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.44.0" +version = "1.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9975ea0f48b5aa3972bf2d888c238182458437cc2a19374b81b25cdf1023fb3a" +checksum = "2513ca694ef9ede0fb23fe71a4ee4107cb102b9dc1930f6d0fd77aae068ae165" dependencies = [ "backtrace", "bytes", diff --git a/editor/src/messages/portfolio/document/overlays/utility_types.rs b/editor/src/messages/portfolio/document/overlays/utility_types.rs index 2bc4830c..f249f0c5 100644 --- a/editor/src/messages/portfolio/document/overlays/utility_types.rs +++ b/editor/src/messages/portfolio/document/overlays/utility_types.rs @@ -734,7 +734,7 @@ impl OverlayContext { ); } - self.render_context.set_font("12px Source Sans Pro, Arial, sans-serif"); + self.render_context.set_font(r#"12px "Source Sans Pro", Arial, sans-serif"#); self.render_context.set_fill_style_str(font_color); self.render_context.fill_text(text, 0., 0.).expect("Failed to draw the text at the calculated position"); self.render_context.reset_transform().expect("Failed to reset the render context transform"); diff --git a/frontend/README.md b/frontend/README.md index aaf19359..8e451aec 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -22,7 +22,7 @@ Wraps the editor backend codebase (`/editor`) and provides a JS-centric API for ## ESLint configurations: `.eslintrc.js` -[ESLint](https://eslint.org/) is the tool which enforces style rules on the JS, TS, and Svelte files in our frontend codebase. As it is set up in this config file, ESLint will complain about bad practices and often help reformat code automatically when (in VS Code) the file is saved or `npm run lint` is executed. (If you don't use VS Code, remember to run this command before committing!) This config file for ESLint sets our style preferences and configures our usage of extensions/plugins for Svelte support, [Airbnb](https://github.com/airbnb/javascript)'s popular catalog of sane defaults, and [Prettier](https://prettier.io/)'s role as a code formatter. +[ESLint](https://eslint.org/) is the tool which enforces style rules on the JS, TS, and Svelte files in our frontend codebase. As it is set up in this config file, ESLint will complain about bad practices and often help reformat code automatically when (in VS Code) the file is saved or `npm run lint` is executed. (If you don't use VS Code, remember to run this command before committing!) This config file for ESLint sets our style preferences and configures our usage of extensions/plugins for Svelte support and [Prettier](https://prettier.io/)'s role as a code formatter. ## npm ecosystem packages: `package.json` diff --git a/frontend/index.html b/frontend/index.html index 34ca17b1..1e834df4 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1,79 +1,54 @@ - + - - - Graphite - - - - - - - - - - - - - - - - - - - - - + @keyframes spinning-loading-indicator { + 0% { + transform: translate(-30px, -30px) rotate(0deg); + } + 100% { + transform: translate(-30px, -30px) rotate(360deg); + } + } + + + diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 6a1c360d..3d12766c 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -7,7 +7,8 @@ "name": "graphite-web-frontend", "license": "Apache-2.0", "dependencies": { - "@tauri-apps/api": "^2.2.0", + "@fontsource/inconsolata": "^5.2.5", + "@fontsource/source-sans-pro": "^5.2.5", "class-transformer": "^0.5.1", "idb-keyval": "^6.2.1", "reflect-metadata": "^0.2.2" @@ -555,6 +556,21 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@fontsource/inconsolata": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/@fontsource/inconsolata/-/inconsolata-5.2.5.tgz", + "integrity": "sha512-OvzkZY5qYghv/jEV6cfGZzFhdFTvSnU+ExPC7WcZ7w8PdRhtiu/SpcBWOBt+3LXgS0n9qyepgq4zZmxlDTlGGQ==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, + "node_modules/@fontsource/source-sans-pro": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/@fontsource/source-sans-pro/-/source-sans-pro-5.2.5.tgz", + "integrity": "sha512-ypendqc4pYUc+EgF7qqPY9iVYEz1t/Qr03VojKxG/2g3dnpHa1B6DOlDxWQjQXDj5QrG6inEqGT0g+edjALZyg==", + "license": "OFL-1.1" + }, "node_modules/@humanwhocodes/config-array": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", @@ -1050,16 +1066,6 @@ "vite": "^5.0.0" } }, - "node_modules/@tauri-apps/api": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.2.0.tgz", - "integrity": "sha512-R8epOeZl1eJEl603aUMIGb4RXlhPjpgxbGVEaqY+0G5JG9vzV/clNlzTeqc+NLYXVqXcn8mb4c5b9pJIUDEyAg==", - "license": "Apache-2.0 OR MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/tauri" - } - }, "node_modules/@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", diff --git a/frontend/package.json b/frontend/package.json index 838987db..ea18e0fb 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -29,6 +29,8 @@ "wasm:watch-production": "cargo watch --postpone --watch-when-idle --workdir=wasm --shell \"wasm-pack build . --release --target=web -- --color=always\"" }, "dependencies": { + "@fontsource/inconsolata": "^5.2.5", + "@fontsource/source-sans-pro": "^5.2.5", "class-transformer": "^0.5.1", "idb-keyval": "^6.2.1", "reflect-metadata": "^0.2.2" diff --git a/frontend/src/main.ts b/frontend/src/main.ts index 8062e6e6..8ab407bb 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -1,6 +1,13 @@ // This file is the browser's entry point for the JS bundle -// reflect-metadata allows for runtime reflection of types in JavaScript. +// Fonts +import "@fontsource/inconsolata"; +import "@fontsource/source-sans-pro/400-italic.css"; +import "@fontsource/source-sans-pro/400.css"; +import "@fontsource/source-sans-pro/700-italic.css"; +import "@fontsource/source-sans-pro/700.css"; + +// `reflect-metadata` allows for runtime reflection of types in JavaScript. // It is needed for class-transformer to work and is imported as a side effect. // The library replaces the Reflect API on the window to support more features. import "reflect-metadata"; diff --git a/website/.eslintrc.js b/website/.eslintrc.js index 5cbe47b7..451b405a 100644 --- a/website/.eslintrc.js +++ b/website/.eslintrc.js @@ -9,11 +9,13 @@ module.exports = { ecmaVersion: 2020, }, extends: [ - // JS defaults - "airbnb-base", - // General Prettier defaults + "eslint:recommended", + "plugin:import/recommended", + "plugin:@typescript-eslint/recommended", + "plugin:import/typescript", "prettier", ], + plugins: ["import", "@typescript-eslint", "prettier"], settings: { // https://github.com/import-js/eslint-plugin-import#resolvers "import/resolver": { @@ -30,7 +32,6 @@ module.exports = { "!.*.js", "!.*.ts", ], - plugins: ["prettier"], rules: { // Standard ESLint config indent: "off", diff --git a/website/.gitignore b/website/.gitignore index d35f3b5b..0fc0af5d 100644 --- a/website/.gitignore +++ b/website/.gitignore @@ -1,3 +1,5 @@ node_modules/ public/ +static/fonts/ static/syntax-highlighting.css +static/text-balancer.js diff --git a/website/config_prod.toml b/website/config_prod.toml deleted file mode 100644 index 9287f64b..00000000 --- a/website/config_prod.toml +++ /dev/null @@ -1,17 +0,0 @@ -title = "Graphite" -description = "2D raster & vector editor that melds traditional layers & tools with a modern node-based procedural workflow." -base_url = "https://graphite.rs" -feed_filenames = ["rss.xml"] - -compile_sass = true -minify_html = true - -[markdown] -highlight_code = true -highlight_theme = "css" -highlight_themes_css = [ - { theme = "kronuz", filename = "syntax-highlighting.css" }, -] - -[extra] -# Put all your custom variables here diff --git a/website/content/_index.md b/website/content/_index.md index 4d4b2576..98d7c321 100644 --- a/website/content/_index.md +++ b/website/content/_index.md @@ -3,12 +3,14 @@ title = "Free online vector editor & procedural design tool" template = "section.html" [extra] -css = ["/page/index.css", "/component/carousel.css", "/component/feature-icons.css", "/component/feature-box.css", "/component/youtube-embed.css", "/layout/balance-text.css"] +css = ["/page/index.css", "/component/carousel.css", "/component/feature-icons.css", "/component/feature-box.css", "/component/youtube-embed.css"] js = ["/js/carousel.js", "/js/youtube-embed.js", "/js/video-autoplay.js"] -linked_js = ["https://static.graphite.rs/text-balancer/text-balancer.js"] +linked_js = [] meta_description = "Open source free software. A vector graphics creativity suite with a clean, intuitive interface. Opens instantly (no signup) and runs locally in a browser. Exports SVG, PNG, JPG." +++ + + {%- if not page.summary -%} -{{ throw(message = "ARTICLE HAS NO SUMMARY! After the first paragraph (or two short ones), a `` comment must be inserted in the markdown. Otherwise the blog page would be missing its preview text." | safe) }} +{{ throw(message = "------------------------------------------------------------> ARTICLE HAS NO SUMMARY! After the first paragraph (or two short ones), a `` comment must be inserted in the markdown. Otherwise the blog page would be missing its preview text." | safe) }} {%- endif -%} {%- endblock content -%} diff --git a/website/templates/base.html b/website/templates/base.html index 7a49bfe6..d3ed68c4 100644 --- a/website/templates/base.html +++ b/website/templates/base.html @@ -27,15 +27,19 @@ {% block rss -%} {%- endblock %} - - + {#- ======================================================================== -#} + {#- ON EVERY PAGE OF THE SITE: CSS AND JS TO LOAD EITHER AS A LINK OR INLINE -#} {#- ======================================================================== -#} - {%- set global_linked_css = ["https://fonts.googleapis.com/css2?family=Bona+Nova:wght@700&family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap"] -%} {%- set global_linked_js = [] -%} - {%- set global_css = ["/base.css"] -%} + {%- set global_linked_css = [] -%} {%- set global_js = ["/js/text-justification.js", "/js/navbar.js"] -%} + {%- set global_css = ["/base.css", "/fonts/common.css"] -%} + {%- set fonts_loaded = load_data(path="static/fonts/common.css", format="plain", required=false) -%} + {%- if not fonts_loaded -%} + {{ throw(message="------------------------------------------------------------> FONTS ARE NOT INSTALLED! Before running Zola, execute `npm run install-fonts` from the `/website` directory.") }} + {%- endif -%} {#- RETRIEVE FROM TEMPLATES AND PAGES: CSS AND JS TO LOAD EITHER AS A LINK OR INLINE -#} {#- ================================================================================ -#} @@ -89,6 +93,7 @@ {{ load_data(path = path) | safe }} {{ "" | safe }} {%- endfor %} + {{- get_env(name = "INDEX_HTML_HEAD_INCLUSION", default = "") | safe }} @@ -119,8 +124,10 @@
{%- filter replace(from = "", to = replacements::blog_posts(count = 2)) -%} + {%- filter replace(from = "", to = replacements::text_balancer()) -%} {%- block content -%}{%- endblock -%} {%- endfilter -%} + {%- endfilter -%}