fonteditor-core

repository·master·Indexed 18 days ago

https://github.com/kekee000/fonteditor-core

A library for parsing, transforming, and writing font formats including TTF, WOFF, WOFF2, EOT, SVG, and OTF. It supports glyph adjustment, optimization, and conversion between formats, working in both Node.js and browser environments. The library includes a WASM-based module for WOFF2 encoding and decoding and provides a Font class for high-level manipulation and a TTFHelper for low-level glyph and metadata adjustments.

Tokens
9K
Snippets
35
Records
41
Agent score
63%

What's inside fonteditor-core

  1. Initialize the WOFF2 module with WASM

    master

    The woff2 module requires initialization to load its WebAssembly binary. You must provide the path to the .wasm file.

    Important: You must copy the woff2.wasm file from node_modules/fonteditor-core/woff2/ to your project's public assets folder so it is accessible at runtime.

    import { woff2 } from 'fonteditor-core';
    
    // In browser environments
    await woff2.init('/path/to/woff2.wasm');
  2. Build woff2.wasm from source

    master

    To build the woff2.wasm file, you need to use Emscripten (emsdk).

    1. Install Emscripten version 1.38.48.
    2. Activate the environment.
    3. Clone the Google woff2 repository with submodules.
    4. Run the build script.
    # Install emsdk (version 1.38.48 required)
    ./emsdk install 1.38.48
    ./emsdk activate latest
    source ./emsdk_env.sh
    
    # Build woff2.wasm
    git clone --recurse-submodules https://github.com/google/woff2.git
    sh build.sh
  3. Initialize woff2 support

    master

    The woff2 format uses a WebAssembly (WASM) build of Google's woff2. You must call woff2.init() before attempting to read or write woff2 fonts.

    In Node.js: Simply call woff2.init() and await it.

    In the Browser: Pass the path to the .wasm file to woff2.init('/path/to/woff2.wasm').

    import { createFont, woff2 } from 'fonteditor-core';
    
    // Node.js usage
    await woff2.init();
    const font = createFont(buffer, { type: 'woff2' });
    const woff2Buffer = font.write({ type: 'woff2' });
    
    // Browser usage
    await woff2.init('/assets/woff2.wasm');
    const font = createFont(buffer, { type: 'woff2' });
    const arrayBuffer = font.write({ type: 'woff2' });
  4. Import fonteditor-core in ESM environments

    master

    The library supports both CommonJS and ESM. For modern bundlers (Vite, Webpack 5, Rollup, etc.), use ESM imports. You can import the entire library or specific modules like createFont and woff2.

    // Import the whole library
    import fonteditorCore from 'fonteditor-core';
    
    // Or import specific modules
    import { createFont, woff2 } from 'fonteditor-core';
  5. Use fonteditor-core with TypeScript

    master

    The library includes TypeScript declarations for type safety. When working in browser environments, you may need to import Buffer from buffer if required by your setup.

    import fonteditorCore, { createFont, woff2 } from 'fonteditor-core';
    import { Buffer } from 'buffer'; // If needed in browser environments
    
    // Using Font with type safety
    const font = createFont(buffer, {
      type: 'ttf',
      hinting: true,
      subset: [65, 66, 67], // A, B, C
    });
    
    // All properties and methods are properly typed
    const fontObject = font.get();
    console.log(fontObject.head.xMin);
    
    // Using woff2 with type safety
    async function convertFont(ttfBuffer: ArrayBuffer) {
      await woff2.init('/woff2.wasm');
    
      if (woff2.isInited()) {
        const woff2Buffer = fonteditorCore.ttftowoff2(ttfBuffer);
        return woff2Buffer;
      }
      return null;
    }
  6. Use fonteditor-core in Vue.js

    master

    In Vue.js, initialize the woff2 module within the onMounted lifecycle hook. To avoid SSR issues in Nuxt.js, wrap the component using the <client-only> tag.

    import { onMounted, ref } from 'vue';
    import { woff2 } from 'fonteditor-core';
    
    export default {
      setup() {
        const isWoff2Ready = ref(false);
    
        onMounted(() => {
          woff2.init('/woff2.wasm')
            .then(() => {
              isWoff2Ready.value = true;
            });
        });
    
        return { isWoff2Ready };
      }
    }

    Nuxt.js usage:

    <client-only>
      <font-editor />
    </client-only>
  7. Use the woff2 WASM module for encoding and decoding

    master

    The woff2 module provides WebAssembly-based support for converting between TTF and WOFF2 formats. Because it uses WASM, you must call .init() and wait for the promise to resolve before accessing the encoding or decoding methods.

    • woff2Enc(buffer): Encodes a TTF buffer into a WOFF2 buffer.
    • woff2Dec(buffer): Decodes a WOFF2 buffer into a TTF buffer.
    const woff2 = require('./index');
    
    woff2.init().then(function (woff2) {
        // encode ttf buffer to woff2 buffer
        woff2.woff2Enc(buffer);
        
        // decode woff2 buffer to ttf buffer
        woff2.woff2Dec(buffer);
    });
  8. Use fonteditor-core in React/Next.js

    master

    When using in React or Next.js, initialize the woff2 module within a useEffect hook to ensure it runs on the client side.

    For Next.js App Router, use the 'use client' directive to prevent Server-Side Rendering (SSR) issues, as WASM modules and certain browser APIs are not available during SSR.

    // Next.js App Router requirement
    'use client';
    
    import { useEffect, useState } from 'react';
    import { woff2 } from 'fonteditor-core';
    
    function FontComponent() {
      const [isWoff2Ready, setIsWoff2Ready] = useState(false);
    
      useEffect(() => {
        // Initialize woff2 module
        woff2.init('/woff2.wasm')
          .then(() => {
            setIsWoff2Ready(true);
          });
      }, []);
    
      // Component logic...
    }
  9. How WOFF2 encoding and decoding works

    master

    The woff2 module provides access to the WOFF2 WASM-based compression. Because it relies on WASM, you must initialize it before use. Once initialized, you can use encode to convert a TTF buffer to WOFF2 or decode to convert WOFF2 back to TTF.

    import { woff2 } from 'fonteditor-core';
    
    async function processWoff2(ttfBuffer: ArrayBuffer) {
      // Initialize the WASM module
      await woff2.init();
    
      // Encode TTF to WOFF2
      const woff2Buffer = woff2.encode(ttfBuffer);
    
      // Decode WOFF2 to TTF
      const ttfBuffer = woff2.decode(woff2Buffer);
    }
  10. Configure bundlers for fonteditor-core

    master

    If you encounter issues with ESM imports or transpilation, use the following configurations for your bundler.

    // Webpack 5: Add to transpilation process
    module.exports = {
      module: {
        rules: [
          {
            test: /node_modules\/fonteditor-core/,
            use: {
              loader: 'babel-loader',
              options: {
                presets: ['@babel/preset-env']
              }
            }
          }
        ]
      }
    };
    // Vite: Optimize dependencies and handle CommonJS
    import { defineConfig } from 'vite';
    
    export default defineConfig({
      optimizeDeps: {
        include: ['fonteditor-core']
      },
      build: {
        commonjsOptions: {
          include: [/fonteditor-core/, /node_modules/]
        }
      }
    });
    // Rollup: Use node-resolve and commonjs plugins
    import commonjs from '@rollup/plugin-commonjs';
    import { nodeResolve } from '@rollup/plugin-node-resolve';
    
    export default {
      plugins: [
        nodeResolve(),
        commonjs({
          include: ['node_modules/fonteditor-core/**']
        })
      ]
    };
  11. Troubleshoot fonteditor-core in modern bundlers

    master

    If you encounter issues, check the following:

    1. Ensure you are using the latest version of fonteditor-core.
    2. Verify that the woff2.wasm file is correctly placed in your public assets and is accessible via URL.
    3. For Node.js, ensure your environment supports ESM.
    4. If bundling fails, add fonteditor-core to your bundler's transpilation list (e.g., via babel-loader in Webpack).