Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 10 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,31 +81,16 @@ const buffer = require('fs').promises.readFile('./my.woff');
const buffer = document.getElementById('myfile').files[0].arrayBuffer();

// if running in async context:
const font = opentype.parse(await data);
const font = opentype.parse(await buffer);
console.log(font.supported);

// if not running in async context:
buffer.then(data => {
const font = opentype.parse(data);
// ... play with `font` ...
console.log(font.supported);
})
```

### Loading a font (1.x style)

This example rely on the deprecated `.load()` method

```js
// case 1: from an URL
const font = opentype.load('./fonts/my.woff', {}, {isUrl: true});
// case 2: from filesystem
const font = opentype.load('./fonts/my.woff', {}, {isUrl: false});

// ... play with `font` ...
console.log(font.supported);
```

### Writing a font
Once you have a `Font` object (either by using `opentype.load` or by creating a new one from scratch) you can write it
back out as a binary file.
Expand Down Expand Up @@ -140,7 +125,15 @@ const font = new opentype.Font({
ascender: 800,
descender: -200,
glyphs: glyphs});
font.download();

// case 1: node fs
require('fs').appendFileSync('font.otf', Buffer.from(font.toArrayBuffer()));

// case 2: browser download
const blob = new Blob([font.toArrayBuffer()], {type: 'font/opentype'});
const attr = { download: 'my.otf', href: URL.createObjectURL(blob) }
const anch = Object.assign(document.createElement('a'), attr);
document.body.appendChild(anch).click();
```

If you want to inspect the font, use `font.toTables()`
Expand Down
6 changes: 3 additions & 3 deletions docs/examples/reading-writing.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
<head>
<meta charset="UTF-8">
<title>OpenType writing</title>
<script src="/dist/opentype.js"></script>
<style>
body {
font: 13px Helvetica, arial, freesans, sans-serif;
Expand Down Expand Up @@ -41,7 +40,8 @@ <h1 id="fontFamilyName"></h1>
<div id="glyphs"></div>
</div>

<script>
<script type="module">
import * as opentype from "/dist/opentype.js";

var inFont, outFont;

Expand All @@ -60,7 +60,7 @@ <h1 id="fontFamilyName"></h1>
return ctx;
}

opentype.load('../fonts/FiraSansOT-Medium.otf', function (err, font) {
fetch('../fonts/FiraSansOT-Medium.otf').then(res => res.arrayBuffer()).then(buf => opentype.load(buf)).then(function (err, font) {
if (err) {
console.log(err);
}
Expand Down
72 changes: 28 additions & 44 deletions docs/font-inspector.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
<meta name="description" content="A JavaScript library to manipulate the letterforms of text from the browser or node.js.">
<meta charset="utf-8">
<link rel="stylesheet" href="site.css">
<script src="/dist/opentype.js"></script>
</head>
<body>
<div class="header">
Expand All @@ -22,14 +21,14 @@ <h1>opentype.js</h1>
</div>
</div>

<div class="container">
<form class="container" name="demo">

<div class="explain">
<h1>Font Inspector</h1>
<small>opentype.js is an OpenType and TrueType font parser. Here you can inspect the raw font metadata.</small>
</div>

<input id="file" type="file">
<input name="file" type="file">
<span class="info" id="font-name">Roboto-Black</span>
<canvas id="preview" width="940" height="50" class="text"></canvas>
<div id="message"></div>
Expand Down Expand Up @@ -91,14 +90,15 @@ <h1>Free Software</h1>
</div>

<hr>
</div>
</form>


<script type="module">
import * as opentype from '/dist/opentype.js';

<script>
var font = null;
var fontSize = 32;
var textToRender = 'Grumpy wizards make toxic brew for the evil Queen and Jack.';
var previewPath = null;
const fontSize = 32;
const textToRender = 'Grumpy wizards make toxic brew for the evil Queen and Jack.';

function escapeHtml(unsafe) {
return unsafe
Expand All @@ -124,7 +124,7 @@ <h1>Free Software</h1>
canvas.getContext('2d').scale(pixelRatio, pixelRatio);
}

function renderText() {
function renderText(font) {
if (!font) return;

var previewCanvas = document.getElementById('preview');
Expand Down Expand Up @@ -193,7 +193,7 @@ <h1>Free Software</h1>
document.getElementById('name-table').innerHTML = html;
}

function displayFontData() {
function displayFontData(font) {
var html, tablename, table, property, value;

for (tablename in font.tables) {
Expand Down Expand Up @@ -238,39 +238,25 @@ <h1>Free Software</h1>

function onFontLoaded(font) {
window.font = font;
renderText();
displayFontData();
renderText(font);
displayFontData(font);
}

function onReadFile(e) {
document.getElementById('font-name').innerHTML = '';
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function(e) {
try {
font = opentype.parse(e.target.result, {lowMemory:true});
onFontLoaded(font);
showErrorMessage('');
} catch (err) {
showErrorMessage(err.toString());
if (err.stack) console.log(err.stack);
throw(err);
}
};
reader.onerror = function(err) {
const form = document.forms.demo;
form.file.onchange = async function(e) {
form.fontname.innerText = '';
try {
const buf = e.target.files[0].arrayBuffer();
onFontLoaded(opentype.parse(await buf, {lowMemory:true}));
showErrorMessage('');
} catch (err) {
showErrorMessage(err.toString());
};

reader.readAsArrayBuffer(file);
}
}
};

var fontFileName = 'fonts/FiraSansMedium.woff';

document.getElementById('font-name').innerHTML = fontFileName.split('/')[1];

var fileButton = document.getElementById('file');
fileButton.addEventListener('change', onReadFile, false);

var tableHeaders = document.getElementById('font-data').getElementsByTagName('h3');
for(var i = tableHeaders.length; i--; ) {
tableHeaders[i].addEventListener('click', function(e) {
Expand All @@ -280,14 +266,12 @@ <h1>Free Software</h1>

enableHighDPICanvas('preview');

opentype.load(fontFileName, function(err, font) {
var amount, glyph, ctx, x, y, fontSize;
if (err) {
showErrorMessage(err.toString());
return;
}
onFontLoaded(font);
}, {lowMemory:true});
const buf = await fetch(fontFileName).then(res => res.arrayBuffer());
try {
onFontLoaded(opentype.parse(buf, {lowMemory:true}));
} catch (err) {
showErrorMessage(err.toString());
}
</script>
</body>
</html>
77 changes: 33 additions & 44 deletions docs/glyph-inspector.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
<meta name="description" content="A JavaScript library to manipulate the letterforms of text from the browser or node.js.">
<meta charset="utf-8">
<link rel="stylesheet" href="site.css">
<script src="/dist/opentype.js"></script>
</head>
<body>
<div class="header">
Expand All @@ -22,7 +21,7 @@ <h1>opentype.js</h1>
</div>
</div>

<div class="container">
<form class="container" name="demo">

<div class="explain">
<h1>Glyph Inspector</h1>
Expand Down Expand Up @@ -58,10 +57,14 @@ <h1>Free Software</h1>
</div>

<hr>
</div>
</form>


<script type="module">
import * as opentype from "/dist/opentype.js";

const form = document.forms.demo;

<script>
var cellCount = 100,
cellWidth = 44,
cellHeight = 40,
Expand Down Expand Up @@ -122,6 +125,7 @@ <h1>Free Software</h1>
}

function displayGlyphData(glyphIndex) {
const font = window.font;
var container = document.getElementById('glyph-data');
if (glyphIndex < 0) {
container.innerHTML = '';
Expand Down Expand Up @@ -243,7 +247,7 @@ <h1>Free Software</h1>
height = canvas.height / pixelRatio;
ctx.clearRect(0, 0, width, height);
if(glyphIndex < 0) return;
var glyph = font.glyphs.get(glyphIndex),
var glyph = window.font.glyphs.get(glyphIndex),
glyphWidth = glyph.advanceWidth * glyphScale,
xmin = (width - glyphWidth)/2,
xmax = (width + glyphWidth)/2,
Expand Down Expand Up @@ -272,12 +276,12 @@ <h1>Free Software</h1>
var cellMarkSize = 4;
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, cellWidth, cellHeight);
if (glyphIndex >= font.numGlyphs) return;
if (glyphIndex >= window.font.numGlyphs) return;

ctx.fillStyle = '#606060';
ctx.font = '9px sans-serif';
ctx.fillText(glyphIndex, 1, cellHeight-1);
var glyph = font.glyphs.get(glyphIndex),
var glyph = window.font.glyphs.get(glyphIndex),
glyphWidth = glyph.advanceWidth * fontScale,
xmin = (cellWidth - glyphWidth)/2,
xmax = (cellWidth + glyphWidth)/2,
Expand Down Expand Up @@ -307,7 +311,7 @@ <h1>Free Software</h1>
displayGlyphPage(+event.target.id.substr(1));
}

function initGlyphDisplay() {
function initGlyphDisplay(font) {
var glyphBgCanvas = document.getElementById('glyph-bg'),
w = glyphBgCanvas.width / pixelRatio,
h = glyphBgCanvas.height / pixelRatio,
Expand All @@ -322,7 +326,7 @@ <h1>Free Software</h1>
glyphBaseline = glyphMargin + glyphH * head.yMax / maxHeight;

function hline(text, yunits) {
ypx = glyphBaseline - yunits * glyphScale;
const ypx = glyphBaseline - yunits * glyphScale;
ctx.fillText(text, 2, ypx+3);
ctx.fillRect(80, ypx, w, 1);
}
Expand Down Expand Up @@ -366,40 +370,18 @@ <h1>Free Software</h1>
}
pagination.appendChild(fragment);

initGlyphDisplay();
initGlyphDisplay(font);
displayGlyphPage(0);
displayGlyph(-1);
displayGlyphData(-1);
}

function onReadFile(e) {
document.getElementById('font-name').innerHTML = '';
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function(e) {
try {
font = opentype.parse(e.target.result, {lowMemory:true});
showErrorMessage('');
onFontLoaded(font);
} catch (err) {
showErrorMessage(err.toString());
if (err.stack) console.log(err.stack);
throw(err);
}
};
reader.onerror = function(err) {
showErrorMessage(err.toString());
};

reader.readAsArrayBuffer(file);
}

function cellSelect(event) {
if (!font) return;
if (!window.font) return;
var firstGlyphIndex = pageSelected*cellCount,
cellIndex = +event.target.id.substr(1),
glyphIndex = firstGlyphIndex + cellIndex;
if (glyphIndex < font.numGlyphs) {
if (glyphIndex < window.font.numGlyphs) {
displayGlyph(glyphIndex);
displayGlyphData(glyphIndex);
}
Expand All @@ -423,21 +405,28 @@ <h1>Free Software</h1>
var fontFileName = 'fonts/FiraSansMedium.woff';
document.getElementById('font-name').innerHTML = fontFileName.split('/')[1];

var fileButton = document.getElementById('file');
fileButton.addEventListener('change', onReadFile, false);
form.file.onchange = async function(e) {
form.fontname.innerText = '';
try {
const buf = e.target.files[0].arrayBuffer();
onFontLoaded(opentype.parse(await buf, {lowMemory:true}));
showErrorMessage('');
} catch (err) {
showErrorMessage(err.toString());
}
};

enableHighDPICanvas('glyph-bg');
enableHighDPICanvas('glyph');

prepareGlyphList();
opentype.load(fontFileName, function(err, font) {
var amount, glyph, ctx, x, y, fontSize;
if (err) {
showErrorMessage(err.toString());
return;
}
onFontLoaded(font);
}, {lowMemory:true});

const buf = await fetch(fontFileName).then(res => res.arrayBuffer());
try {
onFontLoaded(opentype.parse(buf, {lowMemory:true}));
} catch (err) {
showErrorMessage(err.toString());
}
</script>
</body>
</html>
Loading