Le brinda acceso a las Formas de letras del texto del navegador o node.js.
Ver https://opentype.js.org/ para una demostración en vivo.
glyf y PostScript cff )Seleccione una de las siguientes fuentes en el siguiente ejemplo:
<!-- using global declaration -->
< script src =" https://your.favorite.cdn/opentype.js " > </ script >
< script > opentype . parse ( ... ) </ script >
<!-- using module declaration (need full path) -->
< script type = module >
import { parse } from "https://unpkg.com/opentype.js/dist/opentype.mjs" ;
parse ( ... ) ;
</ script >npm install opentype.js const opentype = require ( 'opentype.js' ) ;
import opentype from 'opentype.js'
import { load } from 'opentype.js'¿Usando TypeScript? Ver este ejemplo
Si planea mejorar o depurar opentype.js, puede:
git clone git://github.com/yourname/opentype.js.gitcd opentype.jsnpm installnpm run buildnpm run start y navegue a la carpeta /docsnpm run test Esto se hace en dos pasos: primero, cargamos el archivo de fuente en un ArrayBuffer ...
// either from an URL
const buffer = fetch ( '/fonts/my.woff' ) . then ( res => res . arrayBuffer ( ) ) ;
// ... or from filesystem (node)
const buffer = require ( 'fs' ) . promises . readFile ( './my.woff' ) ;
// ... or from an <input type=file id=myfile> (browser)
const buffer = document . getElementById ( 'myfile' ) . files [ 0 ] . arrayBuffer ( ) ; ... Entonces nosotros .parse() en una instancia Font
// if running in async context:
const font = opentype . parse ( await buffer ) ;
console . log ( font ) ;
// if not running in async context:
buffer . then ( data => {
const font = opentype . parse ( data ) ;
console . log ( font ) ;
} )La compresión de Woff2 Brotli funciona un 29% mejor que el predecesor de Woff. Pero esta compresión también es más compleja y daría como resultado una biblioteca mucho más pesada (> 10 ×!) Opentype.js (≈120kb => ≈1400kb).
Para resolver esto: descomprima la fuente de antemano (por ejemplo con Fontello/Wawoff2).
// promise-based utility to load libraries using the good old <script> tag
const loadScript = ( src ) => new Promise ( ( onload ) => document . documentElement . append (
Object . assign ( document . createElement ( 'script' ) , { src , onload } )
) ) ;
const buffer = //...same as previous example...
// load wawoff2 if needed, and wait (!) for it to be ready
if ( ! window . Module ) {
const path = 'https://unpkg.com/[email protected]/build/decompress_binding.js'
const init = new Promise ( ( done ) => window . Module = { onRuntimeInitialized : done } ) ;
await loadScript ( path ) . then ( ( ) => init ) ;
}
// decompress before parsing
const font = opentype . parse ( Module . decompress ( await buffer ) ) ;También es posible crear una fuente desde cero definiendo cada ruta de glifo Bézier.
// 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 ] } ) ; Una vez que tenga un objeto Font (desde la elaboración o desde .parse() ), puede guardarlo nuevamente como archivo.
// using node:fs
fs . writeFileSync ( "out.otf" , Buffer . from ( font . toArrayBuffer ( ) ) ) ;
// using the browser to createElement a <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 ( ) ;Una fuente representa un archivo de fuentes de OpenType cargado. Contiene un conjunto de glifos y métodos para dibujar texto en un contexto de dibujo, o para obtener una ruta que represente el texto.
glyphs : una lista indexada de objetos de glifo.unitsPerEm : las coordenadas X/Y en las fuentes se almacenan como enteros. Este valor determina el tamaño de la cuadrícula. Los valores comunes son 2048 y 4096 .ascender : distancia desde la línea de base del más alto ascender. En unidades de fuentes, no píxeles.descender : distancia desde la línea de base del descender más bajo. En unidades de fuentes, no píxeles. Font.getPath(text, x, y, fontSize, options)Cree una ruta que represente el texto dado.
x : posición horizontal del comienzo del texto. (predeterminado: 0 )y : Posición vertical de la línea de base del texto. (predeterminado: 0 )fontSize : tamaño del texto en píxeles (predeterminado: 72 ).options : {GlyPhrenderOptions} pasada a cada glifo, ver a continuaciónOpciones es un objeto opcional {GlyPhrenderOptions} que contiene:
script : Script utilizado para determinar qué características se aplicar (predeterminado: "DFLT" o "latn" )language : Sistema de idioma utilizado para determinar qué características aplicar (predeterminada: "dflt" )kerning : Si True tiene en cuenta la información de Kerning (predeterminado: true )features : un objeto con etiquetas de características OpenType como claves y un valor booleano para habilitar cada característica. Actualmente, solo se admiten características de ligadura "liga" y "rlig" (predeterminada: true ).hinting : si True usa sugerencias de fuentes TrueType si está disponible (predeterminado: false ).colorFormat : los colores de formato se convierten para renderizar (predeterminado: "hexa" ). Puede ser "rgb" / "rgba" para la salida rgb() / rgba() , "hex" / "hexa" para colores hexadecimales de 6/8 dígitos, o "hsl" / "hsla" para la salida hsl() / hsla() . "bgra" genera un objeto con R, G, B, A Keys (R/G/B de 0-255, A de 0-1). "raw" emite un entero como se usa en la tabla CPAL.fill : color de fuente, el color utilizado para representar cada glifo (predeterminado: "black" ) Nota: También hay Font.getPaths() con los mismos argumentos, que devuelve una lista de rutas.
Font.draw(ctx, text, x, y, fontSize, options)Cree una ruta que represente el texto dado.
ctx : un contexto de dibujo 2D, como el lienzo.x : posición horizontal del comienzo del texto. (predeterminado: 0 )y : Posición vertical de la línea de base del texto. (predeterminado: 0 )fontSize : tamaño del texto en píxeles (predeterminado: 72 ).options : {GlyPhrenderOptions} pasada a cada glifo, ver Font.getPath()Opciones es un objeto opcional que contiene:
kerning : si es true , tiene en cuenta la información de Kerning (predeterminado: true )features : un objeto con etiquetas de características OpenType como claves y un valor booleano para habilitar cada característica. Actualmente, solo se admiten características de ligadura "liga" y "rlig" (predeterminada: true ).hinting : si True usa sugerencias de fuentes TrueType si está disponible (predeterminado: false ). Font.drawPoints(ctx, text, x, y, fontSize, options) Dibuja los puntos de todos los glifos en el texto. Los puntos en la curva se dibujarán en azul, los puntos fuera de la curva se dibujarán en rojo. Los argumentos son los mismos que Font.draw() .
Font.drawMetrics(ctx, text, x, y, fontSize, options)Dibuje líneas que indiquen mediciones de fuente importantes para todos los glifos en el texto. Las líneas negras indican el origen del sistema de coordenadas (punto 0,0). Las líneas azules indican el cuadro delimitador del glifo. La línea verde indica el ancho de avance del glifo.
Font.stringToGlyphs(string)Convierta la cadena en una lista de objetos de glifo. Tenga en cuenta que no existe una correspondencia estricta de 1 a 1 entre la cadena y la lista de glifos debido a posibles sustituciones como ligaduras. La lista de glifos devueltos puede ser mayor o menor que la longitud de la cadena dada.
Font.charToGlyph(char) Convierta el personaje en un objeto de glifo. Devuelve null si no se puede encontrar el glifo. Tenga en cuenta que esta función supone que hay un mapeo uno a uno entre el carácter dado y un glifo; Para los scripts complejos, este podría no ser el caso.
Font.getKerningValue(leftGlyph, rightGlyph) Recupere el valor del par de kerning entre el glifo izquierdo (o su índice) y el glifo derecho (o su índice). Si no se encuentra un par de kerning, regrese 0 . El valor de kerning se agrega al ancho de avance al calcular el espacio entre los glifos.
Font.getAdvanceWidth(text, fontSize, options)Devuelve el ancho de avance de un texto.
Esto es algo diferente a Path.getBoundingBox() ; Por ejemplo, un espacio en blanco sufijo aumenta el ancho de avance, pero no el cuadro delimitador o una carta que sobresalía, como una 'F' caligráfica, podría tener un cuadro delimitador bastante más grande que su ancho de avance.
Esto corresponde a canvas2dContext.measureText(text).width
fontSize : tamaño del texto en píxeles (predeterminado: 72 ).options : {GlyPhrenderOptions} , ver Font.getPath() Font.palettes ( PaletteManager )Esto permite administrar las paletas y los colores en la tabla CPAL, sin tener que modificar la tabla manualmente.
Font.palettes.add(colors)Agregue una nueva paleta.
colors : (opcional) colores para agregar a la paleta, las diferencias a las paletas existentes se llenarán con el valor predeterminado. Font.palettes.delete(paletteIndex)Elimina una paleta por su índice basado en cero
paletteIndex : índice de paleta a base de cero Font.palettes.deleteColor(colorIndex, replacementIndex)Elimina un índice de color específico en todas las paletas y actualiza todas las capas usando ese color con el color que actualmente se mantiene en el índice de reemplazo
colorIndex : índice del color que se debe eliminarreplacementIndex : índice (según la paleta antes de la eliminación) del color para reemplazar en capas utilizando el color para eliminar Font.palettes.cpal()Devuelve la tabla CPAL de la fuente, o falso si no existe. Utilizado internamente.
Font.palettes.ensureCPAL(colors)Se usa principalmente internamente. Se asegura de que la tabla CPAL exista o esté poblada con valores predeterminados.
colors : (opcional) colores para poblar en la creación devuelve true si se creó, false si ya existía. Font.palettes.extend(num)Extienda todas las paletas existentes y el valor de NumpaletteEntries por una serie de ranuras de color
num : Número de ranuras de color adicionales para agregar a todas las paletas Font.palettes.fillPalette(palette, colors, colorCount) Llena un conjunto de colores de la paleta (desde un índice de paleta, o una matriz proporcionada de valores de color CPAL) con un conjunto de colores, que se vuelven al valor de color predeterminado, hasta un recuento dado. ¡No modifica la paleta existente, devolviendo una nueva matriz! Use Font.palettes.setColor() en su lugar si es necesario.
palette : índice de paleta o una variedad de valores de color CPAL para llenar la paleta, el resto se llenará con el color predeterminadocolors : matriz de valores de color para llenar la paleta con, en un formato admitido como una salida de colorFormat en {GlyPhrenderOptions} , ver Font.getPath() . Los nombres de color CSS también son compatibles con el contexto del navegador.colorCount : Número de colores para llenar la paleta con el valor predeterminado al valor del campo Numpaletteentries Font.palettes.getAll(colorFormat)Devuelve una matriz de matrices de valores de color para cada paleta, opcionalmente en un formato de color especificado
colorFormat : (opcional) Ver {GlyPhrenderOptions} en Font.getPath() , (predeterminado: "hexa" ) Font.palettes.getColor(index, paletteIndex, colorFormat)Obtenga una paleta específica por su índice basado en cero
index : índice basado en cero del color en la paletapaletteIndex : índice de paleta basado en cero (predeterminado: 0)colorFormat : (opcional) Ver {GlyPhrenderOptions} en Font.getPath() , (predeterminado: "hexa" ) Font.palettes.get(paletteIndex, colorFormat)Obtenga una paleta específica por su índice basado en cero
paletteIndex : índice de paleta a base de cerocolorFormat : (opcional) Ver {GlyPhrenderOptions} en Font.getPath() , (predeterminado: "hexa" ) Font.palettes.setColor(index, colors, paletteIndex)Establezca uno o más colores en una paleta específica por su índice basado en cero
index : índice de color basado en cero para comenzar a llenarcolor : valor de color o matriz de valores de color en una notación de color admitida como salida de colorFormat en {glyphrenderOptions} , ver Font.getPath() . Los nombres de color CSS también son compatibles con el contexto del navegador.paletteIndex : índice de paleta basado en cero (predeterminado: 0) Font.palettes.toCPALcolor(color)Convierte una cadena de valor de color a un valor de color entero CPAL
color : String en una notación de color admitida como una salida de colorFormat en {GlyPhrenderOptions} , ver Font.getPath() . Los nombres de color CSS también son compatibles con el contexto del navegador. Font.layers ( LayerManager )Esto permite administrar las capas de glifo de color en la tabla COLR, sin tener que modificar la tabla manualmente.
Font.layers.add(glyphIndex, layers, position)Agrega una o más capas a un glifo, al final o en una posición específica.
glyphIndex : índice de glifo para agregar la (s) capa (s) a.layers : objeto de capa {Glyph, PaletteIndex}/{Glyphid, PaletteIndex} o matriz de objetos de capa.position : Posición para insertar las capas en (predeterminará el valor predeterminado al final). Font.layers.ensureCOLR()Se usa principalmente internamente. Asegura que la tabla COLR exista y esté poblada con valores predeterminados.
Font.layers.get(glyphIndex)Obtiene las capas para un glifo específico
glyphIndex devuelve una matriz de objetos de capa {glyph, paletteIndex} . Font.layers.remove(glyphIndex, start, end = start)Elimina una o más capas de un glifo.
glyphIndex : índice de glifo para eliminar la (s) capa (s) destart : índice para eliminar la capa enend : (opcional) Si se proporciona, elimina todas las capas del índice de inicio hasta (e incluyen) el índice final Font.layers.setPaletteIndex(glyphIndex, layerIndex, paletteIndex)Establece una propiedad PaletteIndex de la capa de glifo de color en un nuevo índice
glyphIndex : Glyph en la fuente por índice de glifo basado en cerolayerIndex : capa en el glifo por índice de capa basado en ceropaletteIndex : Nuevo color para establecer la capa por índice basado en cero en cualquier paleta Font.layers.updateColrTable(glyphIndex, layers)Se usa principalmente internamente. Actualiza la tabla COLR, agregando un BaseGlyphrecord si es necesario, asegurando que se inserta en la posición correcta, actualizando numlayers y ajuste los valores de FirstLayerIndex para todos los Baseglyphrecords de acuerdo con cualquier deleción o inserción.
Font.variation ( VariationManager ) El VariationManager maneja las propiedades de fuente variable utilizando las tablas de variación de fuentes OpenType.
Font.variation.activateDefaultVariation()Activa la variación predeterminada estableciendo sus datos de variación como las opciones de renderización predeterminadas de la fuente. Usa la instancia predeterminada si está disponible; De lo contrario, el valor predeterminado es el valor predeterminado a las coordenadas de todos los ejes.
Font.variation.getDefaultCoordinates()Devuelve las coordenadas predeterminadas para los ejes de variación de la fuente.
Font.variation.getDefaultInstanceIndex() Determina y devuelve el índice de la instancia de variación predeterminada. Devuelve -1 si no se puede determinar.
-1 . Font.variation.getTransform(glyph, coords) Solo un atajo para Font.variation.process.getTransform() .
Font.variation.getInstanceIndex(coordinates) Encuentra el índice de la instancia de variación que coincide con las coordenadas proporcionadas, o -1 si ninguno coincide.
coordinates : Objeto con etiquetas de eje como teclas y valores de variación como valores correspondientes.-1 . Font.variation.getInstance(index)Recupera una instancia de variación específica por su índice basado en cero.
index : índice basado en cero de la instancia de variación.null si el índice no es válido. Font.variation.set(instanceIdOrObject)Establece las coordenadas de variación que se utilizarán de forma predeterminada para representar en las opciones de renderización predeterminadas de la fuente.
instanceIdOrObject : el índice basado en cero de una instancia de variación o un eje de mapeo de objeto a los valores de variación. Font.variation.get()Obtiene la configuración de variación actual de las opciones de render de la fuente.
Font.variation.process ( VariationProcessor ) El VariationProcessor es un componente del VariationManager , utilizado principalmente internamente para calcular y aplicar variaciones a los glifos en una fuente variable. Maneja transformaciones y ajustes basados en los ejes e instancias variables de la fuente.
Font.variation.process.getNormalizedCoords(coords)Devuelve coordenadas normalizadas para los ejes de variación en función de la configuración actual.
coords : las coordenadas objeto para normalizar (o las coordenadas de variación en las font de defaultRenderOptions de forma predeterminada)Font.variation.process.interpolatePoints(points, deltas, scalar)Interpolates Puntos basados en Deltas proporcionados y un valor escalar.
points : matriz de puntos originales.deltas : matriz de deltas de puntos.scalar : valor escalar para la interpolación.Font.variation.process.deltaInterpolate(original, deltaValues, scalar)Calcula el valor interpolado para un solo punto dados los valores originales, los deltas y un escalar.
original : Valor original del punto.deltaValues : matriz de valores delta para el punto.scalar : valor escalar para la interpolación.Font.variation.process.deltaShift(points, deltas)Aplica los valores delta a los puntos de cambio.
points : matriz de puntos originales.deltas : matriz de deltas para aplicar.Font.variation.process.transformComponents(components, transformation)Transforma los componentes de un glifo utilizando una matriz de transformación especificada.
components : Componentes del glifo.transformation : matriz de transformación para aplicar.Font.variation.process.getTransform(glyph, coords)Recupera una copia transformada de un glifo basado en las coordenadas de variación proporcionadas, o el glifo en sí si no se aplicó ninguna variación
glyph : glifo o índice de glifo para transformar.coords : Variación COORDS Object (o las coordens de variación en el defaultRenderOptions de la fuente de forma predeterminada)opentype.Glyph Font.variation.process.getVariableAdjustment(adjustment)Calcula el ajuste variable para un parámetro de ajuste dado.
adjustment : parámetro de ajuste.Font.variation.process.getDelta(deltas)Selecciona los valores delta apropiados de una colección de deltas en función de la configuración de variación actual.
deltas : Colección de valores delta.Font.variation.process.getBlendVector()Calcula el vector de mezcla para interpolaciones basadas en la configuración actual.
Un glifo es una marca individual que a menudo corresponde a un carácter. Algunos glifos, como las ligaduras, son una combinación de muchos personajes. Los glifos son los bloques de construcción básicos de una fuente.
font : una referencia al objeto de fuente.name : El nombre del glifo (por ejemplo, "Aring" , "five" )unicode : el valor unicode primario de este glifo (puede ser undefined ).unicodes : la lista de valores de Unicode para este glifo (la mayoría de las veces esto será 1 , también puede estar vacía).index : el número de índice del glifo.advanceWidth : el ancho para avanzar la pluma al dibujar este glifo.leftSideBearing : la distancia horizontal desde el carácter anterior al origen ( 0, 0 ); Un valor negativo indica un voladizoxMin , yMin , xMax , yMax : el cuadro delimitador del glifo.path : el camino crudo y sin calificar del glifo. Glyph.getPath(x, y, fontSize, options, font)Obtenga un objeto de ruta de glifo escalado para usar en un contexto de dibujo.
x : posición horizontal del glifo. (predeterminado: 0 )y : Posición vertical de la línea de base del glifo. (predeterminado: 0 )fontSize : tamaño de fuente en píxeles (predeterminado: 72 ).options : {GlyPhrenderOptions} , ver Font.getPath()font : un objeto de fuente, necesario para representar fuentes Colr/CPAL para obtener las capas y los colores Glyph.getBoundingBox() Calcule el cuadro delimitador mínimo para la ruta sin calificar del glifo dado. Devuelve un objeto opentype.BoundingBox que contiene x1 / y1 / x2 / y2 . Si el glifo no tiene puntos (por ejemplo, un carácter espacial), todas las coordenadas serán cero.
Glyph.draw(ctx, x, y, fontSize, options, font)Dibuja el glifo en el contexto dado.
ctx : el contexto de dibujo.x : posición horizontal del glifo. (predeterminado: 0 )y : Posición vertical de la línea de base del glifo. (predeterminado: 0 )fontSize : tamaño de fuente, en píxeles (predeterminado: 72 ).options : {GlyPhrenderOptions} , ver Font.getPath()font : un objeto de fuente, necesario para representar fuentes Colr/CPAL para obtener las capas y los colores Glyph.drawPoints(ctx, x, y, fontSize, options, font) Dibuja los puntos del glifo en el contexto dado. Los puntos en la curva se dibujarán en azul, los puntos fuera de la curva se dibujarán en rojo. Los argumentos son los mismos que Glyph.draw() .
Glyph.drawMetrics(ctx, x, y, fontSize) Dibuje líneas que indiquen mediciones de fuente importantes para todos los glifos en el texto. Las líneas negras indican el origen del sistema de coordenadas (punto 0,0). Las líneas azules indican el cuadro delimitador del glifo. La línea verde indica el ancho de avance del glifo. Los argumentos son los mismos que Glyph.draw() .
Glyph.toPathData(options) , Glyph.toDOMElement(options) , Glyph.toSVG(options) , Glyph.fromSVG(pathData, options) ,Actualmente, estas son solo funciones de envoltura para sus contrapartes en los objetos de ruta (ver documentación allí), pero puede extenderse en el futuro para transmitir datos de glifos para el cálculo automático.
Glyph.getLayers(font)Obtiene las capas de glifo de color para este glifo de las tablas COLR/CPAL de la fuente especificada
Una vez que tenga una ruta a través de Font.getPath() o Glyph.getPath() , puede usarlo.
commands : la ruta comandos. Cada comando es un diccionario que contiene un tipo y coordenadas. Vea a continuación los ejemplos.fill : el color de llenado del camino. El color es una cadena que representa un color CSS. (predeterminado: 'black' )stroke : el color de trazo del Path . El color es una cadena que representa un color CSS. (predeterminado: null ; la ruta no se acariciará)strokeWidth : el grosor de la línea del Path . (Predeterminado: 1 , pero si stroke es null no se dibujará un accidente cerebrovascular) Path.draw(ctx) Dibuja la ruta en el contexto 2D dado. Esto usa las propiedades de ancho fill , stroke y strokeWidth del objeto de ruta.
ctx : el contexto de dibujo. Path.getBoundingBox() Calcule el cuadro delimitador mínimo para la ruta dada. Devuelve un objeto opentype.BoundingBox que contiene x1 / y1 / x2 / y2 . Si la ruta está vacía (por ejemplo, un carácter espacial), todas las coordenadas serán cero.
Path.toPathData(options)Convierta la ruta a una cadena de instrucciones de datos de ruta. Ver https://www.w3.org/tr/svg/paths.html#pathdata
options :decimalPlaces : la cantidad de lugares decimales para los valores de punto flotante. (predeterminado: 2 )optimize : aplique algunas optimizaciones a los datos de la ruta, por ejemplo, eliminar los comandos innecesarios/duplicados (verdadero/falso, predeterminado: true )flipY : si debe voltear el eje Y de los datos de la ruta, porque las rutas SVG y la fuente usan ejes Y invertidos. ( true : Calcular desde el cuadro delimitador, false : deshabilitar; predeterminado: true )flipYBase : valor base para el cálculo de flipping base. Probablemente querrás calcular esto a partir de los valores de ascender y descendiente de la fuente. (predeterminado: calcule automáticamente el cuadro limitado de los datos de la ruta) Path.toSVG(options) Convierta la ruta a un elemento SVG <path> , como una cadena.
options : Ver Path.toPathData() Path.fromSVG(pathData, options)Recupere la ruta de los datos de la ruta SVG.
Sobrescribe los datos de la ruta para una ruta existente:
const path = new Path ( ) ;
path . fromSVG ( 'M0 0' ) ;O crear una nueva ruta directamente:
const path = Path . fromSVG ( 'M0 0' ) ;pathData : ya sea una cadena de comandos de ruta SVG, o (solo en el contexto del navegador) un SVGPathElementoptions :decimalPlaces , optimize , flipY , flipYBase : ver Path.toPathData()scale : valor de escala aplicado a todas las coordenadas de comando (predeterminado: 1 )x / y : desplazamiento aplicado a todas las coordenadas de comando en el eje x o y (predeterminado: 0 ) {type: 'M', x: 100, y: 200}{type: 'L', x: 100, y: 200}{type: 'C', x1: 0, y1: 50, x2: 100, y2: 200, x: 100, y: 200}{type: 'Q', x1: 0, y1: 50, x: 100, y: 200}{type: 'Z'} Usamos Semver para versiones.
MIT
Nos gustaría reconocer el trabajo de otros sin el cual OpenType.js no sería posible: