### Install opentype.js via npm Source: https://github.com/opentypejs/opentype.js/blob/master/README.md Install the package and import it into your project. ```bash npm install opentype.js ``` ```javascript const opentype = require('opentype.js'); import opentype from 'opentype.js' import { load } from 'opentype.js' ``` -------------------------------- ### Run font generation in Node.js Source: https://github.com/opentypejs/opentype.js/blob/master/docs/examples/README.md Execute the font generation script within the examples directory using the Node.js runtime. ```bash cd opentype.js/examples node generate-font-node.js # This generates a font file, called Pyramid-Regular.otf. ``` -------------------------------- ### Define Glyph Mapping and Geometry Source: https://github.com/opentypejs/opentype.js/blob/master/docs/examples/font-editor.html JavaScript setup for importing opentype.js and defining the coordinate mapping for character glyphs. ```javascript import * as opentype from "/dist/opentype.mjs"; function linePoint(t, x1, y1, x2, y2) { return [x1 + t * (x2 - x1), y1 + t * (y2 - y1)]; } var SCREEN_SCALE = 20; var TTF_SCALE = 80; var gGlyphMap = { 'A': [[0, 0], [4, 10], [8, 0]], 'B': [[0, 0], [0, 10], [5, 10], [5, 5], [7, 5], [7, 0]], 'C': [[0, 0], [0, 10], [8, 10], [8, 6], [3, 6], [3, 4], [8, 4], [8, 0]], 'D': [[0, 0], [0, 3], [2, 3], [2, 7], [0, 7], [0, 10], [8, 10], [8, 0]], 'E': [[0, 0], [0, 3], [0, 10], [8, 10], [8, 7], [3, 7], [3, 6], [5, 6], [5, 4], [3, 4], [3, 3], [8, 3], [8, 0]], 'F': [[0, 0], [0, 3], [0, 10], [8, 10], [8, 7], [3, 7], [3, 6], [5, 6], [5, 3], [3, 3], [3, 0]], 'G': [[0, 0], [0, 3], [0, 10], [8, 10], [8, 7], [3, 7], [3, 3], [5, 3], [5, 5], [8, 5], [8, 0]], 'H': [[0, 0], [0, 3], [0, 7], [0, 10], [3, 10], [3, 7], [5, 7], [5, 10], [8, 10], [8, 0], [5, 0], [5, 3], [3, 3], [3, 0]], 'I': [[0, 0], [0, 10], [3, 10], [3, 0]], 'J': [[0, 0], [0, 3], [4, 3], [4, 10], [7, 10], [7, 0]], 'K': [[0, 0], [0, 10], [3, 10], [3, 7], [5, 10], [8, 10], [5, 5], [8, 0], [5, 0], [3, 3], [3, 0]], 'L': [[0, 0], [0, 10], [3, 10], [3, 3], [7, 3], [7, 0]], 'M': [[0, 0], [0, 10], [3, 10], [4, 8], [5, 10], [8, 10], [8, 0], [5, 0], [5, 4], [4, 3], [3, 4], [3, 0]], 'N': [[0, 0], [0, 10], [3, 10], [3, 9], [5, 7], [5, 10], [8, 10], [8, 0], [5, 0], [5, 3], [3, 5], [3, 0]], 'O': [[0, 0], [0, 10], [7, 10], [7, 0]], 'P': [[0, 0], [0, 10], [7, 10], [7, 4], [3, 4], [3, 0]], 'Q': [[0, 0], [0, 10], [7, 10], [7, 0], [6, 0], [7, -1], [4, -1], [3, 0]], 'R': [[0, 0], [0, 10], [7, 10], [7, 4], [5, 4], [7, 0], [4, 0], [3, 2], [3, 0]], 'S': [[7, 10], [7, 7], [3, 7], [3, 6], [7, 6], [7, 0], [0, 0], [0, 3], [4, 3], [4, 4], [0, 4], [0, 10]], 'T': [[2, 0], [2, 7], [0, 7], [0, 10], [7, 10], [7, 7], [5, 7], [5, 0]], 'U': [[0, 0], [0, 10], [3, 10], [3, 3], [5, 3], [5, 10], [8, 10], [8, 0]], 'V': [[0, 10], [3, 10], [4, 6], [5, 10], [8, 10], [5, 0], [3, 0]], 'W': [[0, 10], [3, 10], [4, 6], [5, 8], [6, 6], [7, 10], [10, 10], [8, 0], [6, 0], [5, 3], [4, 0], [2, 0]], 'X': [[0, 10], [3, 10], [4, 8], [5, 10], [8, 10], [5, 5], [8, 0], [5, 0], [4, 2], [3, 0], [0, 0], [3, 5]], 'Y': [[0, 10], [3, 10], [4, 8], [5, 10], [8, 10], [5, 5], [5, 0], [3, 0], [3, 5]], 'Z': [[0, 10], [7, 10], [7, 7], [3, 3], [7, 3], [7, 0], [0, 0], [0, 3], [4, 7], [0, 7]], '_': [[0, 0], [0, 1], [8, 1], [8, 0]], }; // We map between the character and the internal name. var TT ``` -------------------------------- ### Saving a Font Source: https://github.com/opentypejs/opentype.js/blob/master/README.md Provides examples for saving a Font object to a file, both in Node.js and browser environments. ```APIDOC ## Saving a Font Once you have a `Font` object (from crafting or from `.parse()`) you can save it back out as file. ```js // using node:fs fs.writeFileSync("out.otf", Buffer.from(font.toArrayBuffer())); // using the browser to createElement a that will be clicked const href = window.URL.createObjectURL(new Blob([font.toArrayBuffer()]), {type: "font/opentype"}); Object.assign(document.createElement('a'), {download: "out.otf", href}).click(); ``` ``` -------------------------------- ### Get All Color Palettes Source: https://context7.com/opentypejs/opentype.js/llms.txt Retrieves all color palettes from the CPAL table in the specified format. ```javascript const font = opentype.parse(colorFontBuffer); const palettes = font.palettes.getAll('hexa'); console.log('Number of palettes:', palettes.length); console.log('First palette colors:', palettes[0]); // ['#ff0000ff', '#00ff00ff', '#0000ffff', ...] ``` -------------------------------- ### Add Glyph Path to Context Source: https://github.com/opentypejs/opentype.js/blob/master/docs/examples/font-editor.html Adds a series of moveTo and lineTo commands to the canvas context based on the provided points, offset, and scale. Assumes the context's path has already been started. ```javascript function addGlyphPath(ctx, points, x, y, scale) { var x1 = x + points[0][0] * scale; var y1 = y + points[0][1] * scale; ctx.moveTo(x1, y1); var x2; var y2; for (var i = 1; i < points.length; i++) { x2 = x + points[i][0] * scale; y2 = y + points[i][1] * scale; ctx.lineTo(x2, y2); } } ``` -------------------------------- ### Get Specific Color Palette Source: https://context7.com/opentypejs/opentype.js/llms.txt Retrieves a single palette by its index. ```javascript const font = opentype.parse(colorFontBuffer); const palette = font.palettes.get(0, 'rgba'); console.log('Palette 0:', palette); // ['rgba(255, 0, 0, 1)', 'rgba(0, 255, 0, 1)', ...] ``` -------------------------------- ### Create and Render Fonts with OpenType.js Source: https://github.com/opentypejs/opentype.js/blob/master/docs/examples/creating-fonts.html Demonstrates importing the library, defining glyph paths, constructing a font object, and rendering glyphs to a canvas. ```javascript import * as opentype from "/dist/opentype.mjs"; function hexDump(bytes) { var hexString = bytes.map(function(v) { var h = v.toString(16); return h.length === 1 ? '0' + h : h; }); return hexString.join(' ').toUpperCase(); } // Create a canvas and adds it to the document. // Returns the 2d drawing context. function createGlyphCanvas(glyph, size) { var canvasId, html, glyphsDiv, wrap, canvas, ctx; canvasId = 'c' + glyph.index; html = '
' + glyph.index + '
'; glyphsDiv = document.getElementById('glyphs'); wrap = document.createElement('div'); wrap.innerHTML = html; glyphsDiv.appendChild(wrap); canvas = document.getElementById(canvasId); ctx = canvas.getContext('2d'); return ctx; } var notdefPath = new opentype.Path(); notdefPath.moveTo(100, 0); notdefPath.lineTo(100, 700); notdefPath.lineTo(600, 700); notdefPath.lineTo(600, 0); notdefPath.moveTo(200, 100); notdefPath.lineTo(500, 100); notdefPath.lineTo(500, 600); notdefPath.lineTo(200, 600); var notdefGlyph = new opentype.Glyph({ name: '.notdef', unicode: 0, advanceWidth: 650, path: notdefPath }); var aPath = new opentype.Path(); aPath.moveTo(100, 0); aPath.lineTo(100, 700); aPath.lineTo(600, 700); aPath.lineTo(600, 0); aPath.lineTo(500, 0); aPath.lineTo(500, 300); aPath.lineTo(200, 300); aPath.lineTo(200, 0); aPath.moveTo(200, 400); aPath.lineTo(500, 400); aPath.lineTo(500, 600); aPath.lineTo(200, 600); var aGlyph = new opentype.Glyph({ name: 'A', unicode: 65, advanceWidth: 650, path: aPath }); var bPath = new opentype.Path(); bPath.moveTo(100, 0); bPath.lineTo(100, 700); bPath.lineTo(500, 700); bPath.lineTo(500, 400); bPath.lineTo(600, 400); bPath.lineTo(600, 0); bPath.moveTo(200, 400); bPath.lineTo(400, 400); bPath.lineTo(400, 600); bPath.lineTo(200, 600); bPath.moveTo(200, 100); bPath.lineTo(500, 100); bPath.lineTo(500, 300); bPath.lineTo(200, 300); var bGlyph = new opentype.Glyph({ name: 'B', unicode: 66, advanceWidth: 650, path: bPath }); var glyphs = [notdefGlyph, aGlyph, bGlyph]; var font = new opentype.Font({familyName: 'OpenTypeSans', styleName: 'Medium', unitsPerEm: 1000, ascender: 800, descender: -200, glyphs: glyphs}); console.log(font.toTables()); var buffer = font.toArrayBuffer(); var font2 = opentype.parse(buffer); for (var i = 0; i < font2.glyphs.length; i++) { var glyph = font2.glyphs.get(i); var ctx = createGlyphCanvas(glyph, 150); var x = 50; var y = 120; var fontSize = 72; glyph.draw(ctx, x, y, fontSize, {}, font2); glyph.drawPoints(ctx, x, y, fontSize); glyph.drawMetrics(ctx, x, y, fontSize); } const form = document.forms.demo; form.fontFamilyName.innerText = font2.names.windows.fontFamily.en; const a = document.getElementById('download-font'); a.href = window.URL.createObjectURL(new Blob([font2.toArrayBuffer()], {type: "font/otf"})) ``` -------------------------------- ### Initialize Font Rendering Environment Source: https://github.com/opentypejs/opentype.js/blob/master/docs/font-inspector.html Sets up the initial configuration for font rendering, including feature tags for Arabic and Latin scripts. ```javascript import * as opentype from "/dist/opentype.mjs"; var font = null; const fontSize = 32; const drawOptions = { kerning: true, features: [ /** * these 4 features are required to render Arabic text properly * and shouldn't be turned off when rendering arabic text. */ { script: 'arab', tags: ['init', 'medi', 'fina', 'rlig'] }, { script: 'latn', tags: ['liga', 'rlig'] } ] }; ``` -------------------------------- ### Get Variation Instance Source: https://context7.com/opentypejs/opentype.js/llms.txt Retrieves a specific variation instance by its zero-based index. ```javascript const font = opentype.parse(variableFontBuffer); const instance = font.variation.getInstance(2); console.log('Instance:', instance); // { name: { en: 'Bold' }, coordinates: { wght: 700 } } ``` -------------------------------- ### Get Current Variation Coordinates Source: https://context7.com/opentypejs/opentype.js/llms.txt Retrieves the currently active variation coordinates. ```javascript const font = opentype.parse(variableFontBuffer); font.variation.set({ wght: 600 }); const coords = font.variation.get(); console.log('Current variation:', coords); // { wght: 600, ... } ``` -------------------------------- ### Initialize Glyph Display Source: https://github.com/opentypejs/opentype.js/blob/master/docs/glyph-inspector.html Sets up the canvas environment and scaling factors for font visualization. ```javascript function initGlyphDisplay(font) { var glyphBgCanvas = document.getElementById('glyph-bg'), w = glyphBgCanvas.width / pixelRatio, h = glyphBgCanvas.height / pixelRatio, glyphW = w - glyphMargin*2, glyphH = h - glyphMargin*2, head = font.tables.head, maxHeight = head.yMax - head.yMin, ctx = glyphBgCanvas.getContext('2d'); glyphScale = Math.min(glyphW/(head.xMax - head.xMin), glyphH/maxHeight); glyphSize = glyphScale * font.unitsPerEm; glyphBaseline = glyphMargin + glyphH * head.yMax / maxHeight; function hline(text, yunits) { const ypx = glyphBaseline - yunits * glyphScale; ctx.fillText(text, 2, ypx+3); ctx.fillRect(80, ypx, w, 1); } ctx.clearRect(0, 0, w, h); ctx.fillStyle = '#a0a0a ``` -------------------------------- ### Path.close Source: https://context7.com/opentypejs/opentype.js/llms.txt Closes the current subpath by drawing a line back to the starting point. ```APIDOC ## Path.close() ### Description Closes the current subpath by drawing a line back to the starting point. Also available as `closePath`. ``` -------------------------------- ### Initialization and Event Binding Source: https://github.com/opentypejs/opentype.js/blob/master/docs/glyph-inspector.html Initializes the UI and handles initial font loading from session storage or default file. ```javascript form.file.onchange = function(e) { display(e.target.files[0], e.target.files[0].name); }; enableHighDPICanvas('glyph-bg'); enableHighDPICanvas('glyph'); prepareGlyphList(); const fontData = sessionStorage.getItem('fontData'); if ( fontData ) { const arrayBuffer = base64ToArrayBuffer(fontData); onFontLoaded(opentype.parse(arrayBuffer)); } else { const fontFileName = 'fonts/FiraSansMedium.woff'; display(await fetch(fontFileName), fontFileName); } ``` -------------------------------- ### Initialize Font Environment Source: https://github.com/opentypejs/opentype.js/blob/master/docs/index.html Sets up canvas scaling and loads initial font data from session storage or a default file. ```javascript form.file.onchange = function(e) { display(e.target.files[0], e.target.files[0].name); }; enableHighDPICanvas('preview'); enableHighDPICanvas('snap'); const fontData = sessionStorage.getItem('fontData'); if ( fontData ) { const arrayBuffer = base64ToArrayBuffer(fontData); onFontLoaded(opentype.parse(arrayBuffer)); } else { const fontFileName = 'fonts/FiraSansMedium.woff'; display(await fetch(fontFileName), fontFileName); } ``` -------------------------------- ### Close a path subpath Source: https://context7.com/opentypejs/opentype.js/llms.txt Closes the current path by drawing a line to the starting point. ```javascript const path = new opentype.Path(); path.moveTo(100, 0); path.lineTo(200, 100); path.lineTo(0, 100); path.close(); // Draws line back to (100, 0) ``` -------------------------------- ### Get Default Variation Coordinates Source: https://context7.com/opentypejs/opentype.js/llms.txt Returns the default coordinate values for all defined variation axes. ```javascript const font = opentype.parse(variableFontBuffer); const defaults = font.variation.getDefaultCoordinates(); console.log('Default coordinates:', defaults); // { wght: 400, wdth: 100, slnt: 0 } ``` -------------------------------- ### Initialize and use BoundingBox Source: https://context7.com/opentypejs/opentype.js/llms.txt Creates a new BoundingBox instance to track coordinate extents. ```javascript const bbox = new opentype.BoundingBox(); // Add points bbox.addPoint(10, 20); bbox.addPoint(100, 150); bbox.addPoint(50, 200); console.log('Bounding box:', { x1: bbox.x1, // 10 y1: bbox.y1, // 20 x2: bbox.x2, // 100 y2: bbox.y2 // 200 }); // Check if empty console.log('Is empty:', bbox.isEmpty()); // false ``` -------------------------------- ### Get Glyph Bounding Box Source: https://context7.com/opentypejs/opentype.js/llms.txt Calculates the minimum bounding box for the unscaled path of a glyph. ```javascript const font = opentype.parse(buffer); const glyph = font.charToGlyph('W'); const bbox = glyph.getBoundingBox(); console.log('Bounding box:', { x1: bbox.x1, y1: bbox.y1, x2: bbox.x2, y2: bbox.y2, width: bbox.x2 - bbox.x1, height: bbox.y2 - bbox.y1 }); ``` -------------------------------- ### Crafting a Font Source: https://github.com/opentypejs/opentype.js/blob/master/README.md Demonstrates how to create a Font object from scratch by defining glyphs and their paths. ```APIDOC ## Craft a Font It is also possible to craft a Font from scratch by defining each glyph bézier paths. ```javascript // this .notdef glyph is required. const notdefGlyph = new opentype.Glyph({ name: '.notdef', advanceWidth: 650, path: new opentype.Path() }); const aPath = new opentype.Path(); aPath.moveTo(100, 0); aPath.lineTo(100, 700); // more drawing instructions... const aGlyph = new opentype.Glyph({ name: 'A', unicode: 65, advanceWidth: 650, path: aPath }); const font = new opentype.Font({ familyName: 'OpenTypeSans', styleName: 'Medium', unitsPerEm: 1000, ascender: 800, descender: -200, glyphs: [notdefGlyph, aGlyph] }); ``` ``` -------------------------------- ### Create and Populate Path from SVG Source: https://github.com/opentypejs/opentype.js/blob/master/README.md Demonstrates how to create a new Path object and populate it with SVG path data, either by overwriting an existing path or creating a new one. ```javascript const path = new Path(); path.fromSVG('M0 0'); ``` ```javascript const path = Path.fromSVG('M0 0'); ``` -------------------------------- ### Initialize Font Loading Source: https://github.com/opentypejs/opentype.js/blob/master/docs/glyph-inspector.html Configures font rendering options and sets up pagination UI after a font is loaded. ```javascript function onFontLoaded(font) { if (window.font) { window.font.onGlyphUpdated = null } window.font = font; options = Object.assign({}, window.font.defaultRenderOptions); window.fontOptions = options; updateColrOptions(); updateVariationOptions(); var w = cellWidth - cellMarginLeftRight * 2, h = cellHeight - cellMarginTop - cellMarginBottom, head = font.tables.head, maxHeight = head.yMax - head.yMin; fontScale = Math.min(w/(head.xMax - head.xMin), h/maxHeight); fontSize = fontScale * font.unitsPerEm; fontBaseline = cellMarginTop + h * head.yMax / maxHeight; var pagination = document.getElementById("pagination"); pagination.innerHTML = ''; var fragment = document.createDocumentFragment(); var numPages = Math.ceil(font.numGlyphs / cellCount); for(var i = 0; i < numPages; i++) { var link = document.createElement('span'); var lastIndex = Math.min(font.numGlyphs-1, (i+1)*cellCount-1); link.textContent = i*cellCount + '-' + lastIndex; link.id = 'p' + i; link.addEventListener('click', pageSelect, false); fragment.appendChild(link); // A white space allows to break very long lines into multiple lines. // This is needed for fonts with thousands of glyphs. fragment.appendChild(document.createTextNode(' ')); } pagination.appendChild(fragment); initGlyphDisplay(font); displayGlyphPage( ``` -------------------------------- ### Get Glyph Color Layers Source: https://context7.com/opentypejs/opentype.js/llms.txt Retrieves color layer information for a specific glyph from the COLR table. ```javascript const font = opentype.parse(colorFontBuffer); const glyph = font.charToGlyph('A'); const layers = font.layers.get(glyph.index); layers.forEach((layer, i) => { console.log(`Layer ${i}:`, { glyphIndex: layer.glyph.index, paletteIndex: layer.paletteIndex }); }); ``` -------------------------------- ### Initialize Font UI Event Listeners Source: https://github.com/opentypejs/opentype.js/blob/master/docs/font-inspector.html Sets up click listeners for font data headers and the update button. ```javascript document.getElementById('update').addEventListener('click', () => displayFontData(window.font)); var tableHeaders = document.getElementById('font-data').getElementsByTagName('h3'); for(var i = tableHeaders.length; i--; ) { tableHeaders[i].addEventListener('click', function(e) { e.target.className = (e.target.className === 'collapsed') ? 'expanded' : 'collapsed'; }, false); } ``` -------------------------------- ### Move Path Point Source: https://context7.com/opentypejs/opentype.js/llms.txt Moves the current point to specified coordinates without drawing, effectively starting a new subpath. ```javascript const path = new opentype.Path(); path.moveTo(50, 50); path.lineTo(150, 50); path.moveTo(50, 100); // Start new subpath path.lineTo(150, 100); ``` -------------------------------- ### Initialize Canvas and Context Source: https://github.com/opentypejs/opentype.js/blob/master/docs/examples/font-editor.html Sets up the canvas element, retrieves its dimensions, and configures the 2D rendering context for drawing. The context is scaled and translated to invert the y-axis for standard Cartesian coordinates. ```javascript var canvas = document.getElementById('c'); var r = canvas.getBoundingClientRect(); canvas.width = r.width; canvas.height = r.height; var ctx = canvas.getContext('2d'); ctx.scale(1.0, -1.0); ctx.translate(0, -canvas.height); ``` -------------------------------- ### Initialize opentype.js and Global Variables Source: https://github.com/opentypejs/opentype.js/blob/master/docs/glyph-inspector.html Imports the opentype.js library and sets up global variables for font inspection, canvas drawing, and UI elements. This code is typically run once on page load. ```javascript import * as opentype from "/dist/opentype.mjs"; window.opentype = opentype; const form = document.forms.demo; var cellCount = 100, cellWidth = 44, cellHeight = 40, cellMarginTop = 1, cellMarginBottom = 8, cellMarginLeftRight = 1, glyphMargin = 5, pixelRatio = window.devicePixelRatio || 1; var pageSelected, font, fontScale, fontSize, fontBaseline, glyphScale, glyphSize, glyphBaseline; ``` -------------------------------- ### Get Glyph Metrics Source: https://context7.com/opentypejs/opentype.js/llms.txt Retrieves an object containing detailed metrics like xMin, yMin, xMax, yMax, and side bearings. ```javascript const font = opentype.parse(buffer); const glyph = font.charToGlyph('M'); const metrics = glyph.getMetrics(); console.log('Glyph metrics:', metrics); // { xMin: 50, yMin: 0, xMax: 750, yMax: 700, leftSideBearing: 50, rightSideBearing: 50 } ``` -------------------------------- ### Initialize Font Editor Interface Source: https://github.com/opentypejs/opentype.js/blob/master/docs/examples/font-editor.html CSS styles defining the layout and appearance of the font editor application. ```css * { box-sizing: border-box; } /* accent: rgb(26, 70, 102); */ html, body { width: 100%; height: 100%; overflow: hidden; } body { font: 13px helvetica, arial, sans-serif; display: flex; flex-direction: column; background: rgb(24, 29, 32); margin: 0; padding: 0; color: #77c; } header { /*background: #88f;*/ /*background-image: linear-gradient(#88f, #7f7fdf);*/ border-bottom: 1px solid #333366; height: 30px; width: 100%; } header h1 { margin: 0; padding: 0 10px; line-height: 30px; font-size: 18px; } header h1 small { font-size: inherit; opacity: 0.7; } header h1 a { color: inherit; text-decoration: none; border-bottom: 1px solid #88d; } header #download-font { float: right; margin: 4px; border: 1px solid #88d; color: #88d; background: inherit; border-radius: 2px; font-size: 12px; padding: 2px 5px; outline: none; } header #download-font:hover { background: #336; color: #ccc; } #wrap { flex: 1; display: flex; } #glyph-list { width: 220px; overflow-y: scroll; overflow-x: hidden; } #glyph-list svg { display: inline-block; width: 90px; height: 90px; } #glyph-list svg.active { background: rgb(26, 70, 102); } #editor { flex: 1; display: flex; flex-direction: column; position: relative; } #editor #c { flex: 1; border-bottom: 1px solid #333366; } #buttons { position: absolute; top: 35px; left: 225px; } #buttons button { border: 1px solid #558; font-weight: bold; background: rgb(24, 29, 32); color: #558; font-size: 12px; outline: none; border-radius: 2px; margin-right: 10px; } #buttons span { color: #558; } #editor #preview-text-field { height: 30px; line-height: 30px; background: inherit; border: none; border-bottom: 1px solid #333366; padding: 0 10px; color: #88f; outline: none; } #editor #preview { height: 100px; } #code { position: absolute; bottom: 0; right: 0; height: 100px; overflow: hidden; background: inherit; border: none; border-left: 1px solid #336; color: #88f; outline: none; } ``` -------------------------------- ### Path.extend Source: https://context7.com/opentypejs/opentype.js/llms.txt Adds commands from another path or array of commands to this path. ```APIDOC ## Path.extend(pathOrCommands) ### Description Adds commands from another path or array of commands to this path. ``` -------------------------------- ### Get Glyph Path Source: https://context7.com/opentypejs/opentype.js/llms.txt Retrieves a scaled Path object for a glyph. The font parameter is required for color glyphs and variable font variations. ```javascript const font = opentype.parse(buffer); const glyph = font.glyphs.get(65); // Get glyph by index const path = glyph.getPath(100, 200, 72, {}, font); path.fill = '#333'; path.draw(ctx); // For color fonts const colorPath = glyph.getPath(100, 200, 72, { usePalette: 0, drawLayers: true }, font); colorPath.draw(ctx); ``` -------------------------------- ### Include opentype.js via CDN Source: https://github.com/opentypejs/opentype.js/blob/master/README.md Load the library using global script tags or ES modules. ```html ``` -------------------------------- ### Get Kerning Value Between Glyphs Source: https://context7.com/opentypejs/opentype.js/llms.txt Returns the kerning value between two glyphs, which is added to the advance width for spacing. Useful for fine-tuning character spacing. ```javascript const font = opentype.parse(buffer); const glyphA = font.charToGlyph('A'); const glyphV = font.charToGlyph('V'); const kerning = font.getKerningValue(glyphA, glyphV); console.log(`Kerning between A and V: ${kerning} units`); // Convert to pixels at a specific font size const fontSize = 72; const kerningPx = kerning * (1 / font.unitsPerEm) * fontSize; console.log(`Kerning at ${fontSize}px: ${kerningPx}px`); ``` -------------------------------- ### Get Text Advance Width Source: https://context7.com/opentypejs/opentype.js/llms.txt Returns the advance width of a text string in pixels, equivalent to canvas2dContext.measureText(text).width. Useful for layout calculations and centering text. ```javascript const font = opentype.parse(buffer); const text = 'Hello World'; const fontSize = 48; const width = font.getAdvanceWidth(text, fontSize); console.log(`Text width: ${width}px`); // Use for centering text const canvasWidth = 800; const x = (canvasWidth - width) / 2; font.draw(ctx, text, x, 100, fontSize); // Compare with and without kerning const widthWithKerning = font.getAdvanceWidth('AVATAR', 48, { kerning: true }); const widthWithoutKerning = font.getAdvanceWidth('AVATAR', 48, { kerning: false }); console.log(`With kerning: ${widthWithKerning}px`); console.log(`Without kerning: ${widthWithoutKerning}px`); ``` -------------------------------- ### Glyph List and Selection Management Source: https://github.com/opentypejs/opentype.js/blob/master/docs/glyph-inspector.html Functions to initialize the glyph list UI and handle user selection events on canvas elements. ```javascript 0); displayGlyph(-1); displayGlyphData(-1); font.onGlyphUpdated = (glyphId) => { const firstGlyph = pageSelected * cellCount; if (firstGlyph <= glyphId && glyphId < firstGlyph + cellCount) { renderGlyphItem(document.getElementById('g'+(glyphId - firstGlyph)), glyphId); } }; } function cellSelect(event) { if (!window.font) return; var firstGlyphIndex = pageSelected*cellCount, cellIndex = +event.target.id.substr(1), glyphIndex = firstGlyphIndex + cellIndex; if (glyphIndex < window.font.numGlyphs) { displayGlyph(glyphIndex); displayGlyphData(glyphIndex); } } function prepareGlyphList() { var marker = document.getElementById('glyph-list-end'), parent = marker.parentElement; for(var i = 0; i < cellCount; i++) { var canvas = document.createElement('canvas'); canvas.width = cellWidth; canvas.height = cellHeight; canvas.className = 'item'; canvas.id = 'g'+i; canvas.addEventListener('click', cellSelect, false); canvas.addEventListener('keypress', (ev) => ev.keyCode === 13 && cellSelect(ev) , false); canvas.tabIndex = 0; enableHighDPICanvas(canvas); parent.insertBefore(canvas, marker); } } ``` -------------------------------- ### Get Mouse Position Relative to Canvas Source: https://github.com/opentypejs/opentype.js/blob/master/docs/examples/font-editor.html Calculates the mouse coordinates relative to the canvas element's top-left corner, accounting for the canvas's position on the page. ```javascript function getMousePosition(e) { var r = canvas.getBoundingClientRect(); return { x: e.clientX - r.left, y: e.clientY - r.top }; } ``` -------------------------------- ### Extend path with commands Source: https://context7.com/opentypejs/opentype.js/llms.txt Merges commands from another path into the current path instance. ```javascript const path1 = new opentype.Path(); path1.moveTo(0, 0); path1.lineTo(100, 0); const path2 = new opentype.Path(); path2.moveTo(0, 50); path2.lineTo(100, 50); path1.extend(path2); path1.draw(ctx); // Draws both lines ``` -------------------------------- ### Get Individual Glyph Paths Source: https://context7.com/opentypejs/opentype.js/llms.txt Retrieve an array of Path objects, one for each glyph in the text. Useful for styling or manipulating individual glyphs. Paths can be drawn on canvas or converted to SVG. ```javascript const font = opentype.parse(buffer); const paths = font.getPaths('ABC', 0, 100, 72); const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); // Color each glyph differently const colors = ['#FF6B6B', '#4ECDC4', '#45B7D1']; paths.forEach((path, index) => { path.fill = colors[index % colors.length]; path.draw(ctx); }); // Or convert each to SVG const svgElements = paths.map(p => p.toSVG()); ``` -------------------------------- ### Path Object Creation and Drawing Source: https://context7.com/opentypejs/opentype.js/llms.txt Constructor and methods for creating and manipulating Path objects, used for building custom glyph shapes. ```APIDOC ## new opentype.Path() ### Description Creates a new Path object for building custom glyph shapes using drawing commands. ### Constructor `opentype.Path()` ### Properties - **fill** (string) - The fill color of the path. - **stroke** (string) - The stroke color of the path. - **strokeWidth** (number) - The width of the stroke. ### Request Example ```javascript const path = new opentype.Path(); // Set fill and stroke properties path.fill = '#FF0000'; path.stroke = '#000000'; path.strokeWidth = 2; // Build the path with commands path.moveTo(0, 0); path.lineTo(100, 0); path.lineTo(100, 100); path.lineTo(0, 100); path.close(); // Draw on canvas path.draw(ctx); // Or convert to SVG const svg = path.toSVG(); ``` ## Path.moveTo(x, y) ### Description Moves the current point to coordinates (x, y) without drawing. Starts a new subpath. ### Method `moveTo` ### Parameters - **x** (number) - The x-coordinate to move to. - **y** (number) - The y-coordinate to move to. ### Request Example ```javascript const path = new opentype.Path(); path.moveTo(50, 50); path.lineTo(150, 50); path.moveTo(50, 100); // Start new subpath path.lineTo(150, 100); ``` ## Path.lineTo(x, y) ### Description Draws a straight line from the current point to coordinates (x, y). ### Method `lineTo` ### Parameters - **x** (number) - The x-coordinate of the line's end point. - **y** (number) - The y-coordinate of the line's end point. ### Request Example ```javascript const path = new opentype.Path(); path.moveTo(0, 0); path.lineTo(100, 0); path.lineTo(100, 100); path.lineTo(0, 100); path.close(); ``` ## Path.curveTo(x1, y1, x2, y2, x, y) ### Description Draws a cubic Bézier curve from the current point to (x, y) using control points (x1, y1) and (x2, y2). This method is also available as `bezierCurveTo`. ### Method `curveTo` ### Parameters - **x1** (number) - The x-coordinate of the first control point. - **y1** (number) - The y-coordinate of the first control point. - **x2** (number) - The x-coordinate of the second control point. - **y2** (number) - The y-coordinate of the second control point. - **x** (number) - The x-coordinate of the curve's end point. - **y** (number) - The y-coordinate of the curve's end point. ### Request Example ```javascript const path = new opentype.Path(); path.moveTo(0, 100); path.curveTo(50, 0, 150, 0, 200, 100); // Cubic bezier curve path.draw(ctx); ``` ``` -------------------------------- ### Create a custom font from scratch Source: https://github.com/opentypejs/opentype.js/blob/master/README.md Construct a new Font object by defining glyphs with paths and metadata. A .notdef glyph is mandatory for valid OpenType fonts. ```javascript // this .notdef glyph is required. const notdefGlyph = new opentype.Glyph({ name: '.notdef', advanceWidth: 650, path: new opentype.Path() }); const aPath = new opentype.Path(); aPath.moveTo(100, 0); aPath.lineTo(100, 700); // more drawing instructions... const aGlyph = new opentype.Glyph({ name: 'A', unicode: 65, advanceWidth: 650, path: aPath }); const font = new opentype.Font({ familyName: 'OpenTypeSans', styleName: 'Medium', unitsPerEm: 1000, ascender: 800, descender: -200, glyphs: [notdefGlyph, aGlyph]}); ``` -------------------------------- ### Generate Text Path with Options Source: https://context7.com/opentypejs/opentype.js/llms.txt Create a bézier path for given text, with options for kerning, ligatures, hinting, letter spacing, and tracking. The path can be drawn on a canvas or converted to SVG. ```javascript const font = opentype.parse(buffer); // Basic text path const path = font.getPath('Hello World', 0, 150, 72); // Draw on canvas const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); path.fill = 'navy'; path.draw(ctx); ``` ```javascript // With rendering options const pathWithOptions = font.getPath('Typography', 0, 150, 48, { kerning: true, features: { liga: true, rlig: true }, hinting: true, letterSpacing: 0.05, tracking: 50 }); // Convert to SVG const svgPath = pathWithOptions.toSVG(); console.log(svgPath); // Output: ``` -------------------------------- ### Render Glyph to Canvas Source: https://github.com/opentypejs/opentype.js/blob/master/docs/examples/reading-writing.html Creates a canvas element for a specific glyph and returns its 2D drawing context. ```javascript function createGlyphCanvas(glyph, size) { const canvasId = 'c' + glyph.index; const html = '
' + glyph.index + '' + glyph.name + 'U ' + glyph.unicode + '
'; const glyphsDiv = document.getElementById('glyphs'); const wrap = document.createElement('div'); wrap.innerHTML = html; glyphsDiv.appendChild(wrap); const canvas = document.getElementById(canvasId); return canvas.getContext('2d'); } ``` -------------------------------- ### Load and Parse Font Files Source: https://github.com/opentypejs/opentype.js/blob/master/docs/font-inspector.html Asynchronously loads font files, handles WOFF2 decompression using wawoff2, and parses the font data. ```javascript const form = document.forms.demo; async function display(file, name) { form.fontname.innerText = name; const isWoff2 = name.endsWith('.woff2'); if (isWoff2 && !window.Module) { const wasmReady = new Promise((onRuntimeInitialized) => window.Module = { onRuntimeInitialized }); await loadScript('https://unpkg.com/wawoff2@2.0.1/build/decompress_binding.js'); // wawoff2 is globaly loaded as 'Module' await wasmReady; // WASM has called our onRuntimeInitialized() resolver } try { const data = await file.arrayBuffer(); onFontLoaded(opentype.parse(isWoff2 ? Module.decompress(data) : data)); showErrorMessage(''); } catch (err) { showErrorMessage(err.toString()); } } form.file.onchange = function(e) { display(e.target.files[0], e.target.files[0].name); }; enableHighDPICanvas('preview'); const fontFileName = 'fonts/FiraSansMedium.woff'; display(await fetch(fontFileName), fontFileName); ``` -------------------------------- ### Create New Path Source: https://context7.com/opentypejs/opentype.js/llms.txt Instantiates a new Path object for custom shape construction. ```javascript const path = new opentype.Path(); // Set fill and stroke properties path.fill = '#FF0000'; path.stroke = '#000000'; path.strokeWidth = 2; // Build the path with commands path.moveTo(0, 0); path.lineTo(100, 0); path.lineTo(100, 100); path.lineTo(0, 100); path.close(); // Draw on canvas path.draw(ctx); // Or convert to SVG const svg = path.toSVG(); ``` -------------------------------- ### new opentype.Font Source: https://context7.com/opentypejs/opentype.js/llms.txt Creates a new Font object from scratch. ```APIDOC ## new opentype.Font(options) ### Description Creates a new Font object from scratch. Used to programmatically create fonts with custom glyphs. ### Parameters - **options** (Object) - Required - Must include familyName, styleName, unitsPerEm, ascender, and descender properties. ```