Xterm.js: Soporte de ligaduras de fuentes

Creado en 8 sept. 2017  ·  54Comentarios  ·  Fuente: xtermjs/xterm.js

Soporte para ser eliminado en https://github.com/sourcelair/xterm.js/pull/938

Ciertamente, todavía es posible, sin embargo, el renderizador necesita saber a qué personajes unirse.

areapi arerenderer help wanted typenhancement

Comentario más útil

Creo que no estamos interesados ​​en las ligaduras regulares (de hecho, sería malo habilitar ligaduras por li y demás), pero para cosas como == , !== , => y así sucesivamente. Aquí hay una buena lista de ligaduras compatibles con la fuente monospace del código fira:
https://github.com/tonsky/FiraCode/blob/master/showcases/all_ligatures.png

Todos 54 comentarios

Creo que no estamos interesados ​​en las ligaduras regulares (de hecho, sería malo habilitar ligaduras por li y demás), pero para cosas como == , !== , => y así sucesivamente. Aquí hay una buena lista de ligaduras compatibles con la fuente monospace del código fira:
https://github.com/tonsky/FiraCode/blob/master/showcases/all_ligatures.png

¿Qué pasaría si la mitad de la ligadura es de un color diferente? ¿Cómo manejarías eso?

@LoganDark, ¿eso incluso funciona con ligaduras regulares? ¿O se dividen cuando son de diferentes colores?

No y no.

Me pregunto si sería posible extraer el código de renderizado de txtjs, ya que han descubierto cómo renderizar ligaduras, aunque creo que dibujan el texto manualmente. http://txtjs.com/examples/Text/ligatures.html

@devsnek No creo que sea un problema en realidad hacer la representación del texto. El problema es saber qué personaje se une para que se puedan dibujar juntos (actualmente "==" se dibuja como "=" y "=", no como "==").

@Tyriar no se ocuparía el renderizador de fuentes sin nuestra intervención

@devsnek sí, pero cada celda de la cuadrícula se dibuja individualmente con algunas excepciones (emojis, caracteres unicode anchos). Las ligaduras deben incluirse de alguna manera en esa lista. Mire https://github.com/sourcelair/xterm.js/pull/938 para más contexto

@devsnek ES USTED

descargo de responsabilidad: completamente fuera de tema, solo un comentario al azar

@LoganDark, ¿eso incluso funciona con ligaduras regulares? ¿O se dividen cuando son de diferentes colores?

Si vamos por la forma en otros emuladores de los manejan, hacen que se separan si son de diferentes colores, como era de esperar. Esto es casi un requisito, ya que permite que los símbolos se representen correctamente mediante algunos marcadores de idioma en ViM, por ejemplo.

Creo que es totalmente aceptable mostrar los símbolos individuales si el modo de renderizado _no_ es el mismo para todos los caracteres subyacentes.

@ Qix- Mi sugerencia sería dibujar todo el texto a la vez y luego colorear en la publicación. Eso eliminaría cualquier problema con las ligaduras y no requeriría detectar pares de ligaduras (aunque rompería la compatibilidad con fuentes de ancho variable, o incluso con fuentes de espacio único que están ligeramente apagadas / no tienen anchos enteros)

Las ligaduras multicolores de

Sí, no creo que las ligaduras multicolores funcionen. También va en contra de cómo funcionan debajo, donde se dibuja un solo glifo al principio, no varios.

Como aclaración, esto está esperando una buena solución para detectar qué secuencias de caracteres tienen ligaduras. Para hacer esto correctamente, probablemente implicaría un código de bajo nivel que verifica los archivos de fuentes (y, por lo tanto, debería ser un módulo de nodo nativo y no funcionar para los consumidores web), no creo que esta información esté expuesta a la plataforma web.

Ahora que la versión 2.0.0 es estable, tal vez las soluciones de ligadura necesiten una mayor prioridad.

Determinar las asignaciones de glifos manualmente es un hueso duro de roer. Por lo que puedo decir, hacer una experiencia decente de esto requeriría lo siguiente:

  1. Asigne la familia de fuentes seleccionada de nuevo al archivo / búfer que contiene los datos de fuentes reales (otf / ttf / woff / etc)
  2. Analizar los datos de la tabla GSUB de la fuente y traducirlos en un conjunto sensato de reglas para el reemplazo de glifos
  3. Pase algún tipo de mapa o función de mapeo a xterm para determinar qué renderizar para una secuencia de caracteres determinada

Hice algunas búsquedas iniciales con Fira Code (específicamente su variante de fuente nerd) para tratar de descubrir qué tan difícil podría ser cada paso. Todavía no he decidido si me siento lo suficientemente ambicioso (o me preocupo lo suficiente por las ligaduras de fuentes) para asumir esto, pero esto es lo que encontré para que no se pierda el conocimiento:

  • No hay forma de que pueda encontrar los datos de la fuente usando las API del navegador, por lo que esto no funcionará como una característica directa de xterm.js, sino más probablemente como un paquete / extensión separado con un gancho expuesto por xterm.js

  • Mapear el nombre CSS font-family de una fuente de nuevo a su archivo de fuente en Windows es doloroso, pero parece factible. Hasta ahora, la única forma que he encontrado es buscar todo en %WINDIR%\Fonts y analizar cada archivo que encuentre (spoiler: es muy lento). Aún no he probado otras plataformas. (Nota: también intenté eliminar el nombre del registro, pero el nombre no coincide con algunas fuentes, como las de fuentes nerd. Usan una familia y subfamilia "preferidas" que no se incluyen en el nombre del registro. pero se usa en el CSS font-family . Si tiene curiosidad, la clave de registro está en HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts )

  • Hay una biblioteca llamada opentype.js que realiza un análisis completo de las tablas de fuentes OpenType e incluso tiene una función font.stringToGlyphs(str) que maneja ligaduras básicas, pero las ligaduras para Fira Code (y varias, si no todas, las otras fuentes de ligadura comunes) use una función llamada alternativas contextuales que aún no es compatible con opentype.js (listada en Planificado ). Sin embargo, la tabla GSUB necesaria se analiza en JSON, por lo que, en teoría, todo lo que falta es la interpretación de los datos de la tabla.

  • Las ligaduras de Fira Code (y creo que otras) en realidad reemplazan los glifos originales con un número igual de glifos, en lugar de uno solo extra ancho (para mantener las propiedades de la fuente monoespaciada). Para una cadena como ==> , la fuente terminará diciéndote que la reemplaces con dos caracteres "LIG" (esencialmente un espacio vacío), seguidos por el glifo real de la ligadura, que técnicamente es solo un espacio único. carácter amplio. A pesar de ser aparentemente de un solo ancho, la ruta del último carácter se extiende más allá del lado izquierdo del cuadro delimitador del personaje para cubrir el espacio ocupado por los dos caracteres LIG anteriores. Vea a continuación una imagen visual (0 y 600 son los lados del cuadro del personaje). No sé si esto complica la tarea del renderizador o si tendría que transformarse antes de pasar a xterm.js, pero algo a tener en cuenta.

image

  • Otra arruga en esto es determinar cuándo reevaluar la ligadura. Por ejemplo, si escribo = cuatro veces consecutivas, el comportamiento deseado sería ver un simple igual, luego un doble es igual a la ligadura, luego un triple es igual a la ligadura, luego cuatro signos iguales separados. En realidad, hay asignaciones en las reglas alternativas contextuales para borrar la ligadura (es decir, si la entrada actual es '=' y los tres caracteres anteriores son '===', no la reasigne en absoluto), pero tendríamos para averiguar cómo aplicar esas reglas.

  • OpenType es complicado. Es cierto que no soy un experto en renderizado de fuentes, pero el número de posibles variaciones que conducen a diferentes tipos de renderizado es bastante extenso. Sin una biblioteca incorporada que haga el mapeo por nosotros, creo que la forma más razonable de atacar esto es de forma incremental. Fira Code usa específicamente el formato 3 de sustitución de contexto de encadenamiento , pero estoy seguro de que hay otras fuentes populares que usan diferentes. Dado que cada uno tiene una semántica ligeramente diferente, probablemente tenga sentido comenzar con uno e ir desde allí.

@princjef Gracias por compartir sus exploraciones, ¡realmente muy útil! También he estado reflexionando sobre este tema hace un par de días y llegué a la siguiente conclusión:

  • Detectar ligaduras en fuentes web usando una API incorporada parece imposible (tal como lo describe)
  • Hay ciertas ligaduras que no tienen sentido en un terminal, incluso si la fuente lo admite (por ejemplo, li )
  • Hay un subconjunto muy pequeño de ligaduras que tiene sentido ser compatible, a saber, la mayoría de las ligaduras de Fira Code.
  • Agregar soporte para dibujar y borrar un carácter que abarca varias celdas es muy difícil de implementar con nuestro enfoque actual de renderizado basado en un solo carácter (CharAtlas).

TBH, no creo que valga la pena el esfuerzo de admitir ligaduras en el estado actual 😔

@mofux Creo que he encontrado una forma (algo agradable) de hacer que las ligaduras se rendericen en xterm.js acercándome a ellas desde un ángulo diferente. De alguna manera me perdí ese lienzo que automáticamente representará las ligaduras en mis investigaciones iniciales. El soporte de ligaduras se convierte en una cuestión de asegurarse de que los caracteres relevantes se representen juntos.

Con ese fin, modifiqué el renderizador de texto para representar caracteres con atributos idénticos (fg, bg, etc.) como un solo grupo. Esto no representará todas las ligaduras correctamente (y podría representar algunas que no deberían ser), pero debería representar una ligadura en cualquier lugar donde alguien esperaría ver una. Aquí hay una captura de pantalla de NeoVIM en la aplicación de demostración usando Fira Code (que se muestra en Firefox, también funciona en Chrome pero no en Edge):

image

Branch está aquí si la gente quiere echar un vistazo: https://github.com/princjef/xterm.js/tree/ligature-support

Un par de notas sobre esto:

  • No he realizado ninguna evaluación comparativa, pero apuesto a que esto no será bueno para el rendimiento. Al agrupar todos los caracteres del mismo estilo, el atlas de caracteres básicamente se tira por la ventana, incluso para lugares donde no hay ligaduras (ya que no sabemos dónde estarán / no estarán). Cuando renderizo varios caracteres juntos, simplemente configuro el código de carácter en Infinity para asegurarme de evitar cualquier almacenamiento en caché.
  • Probablemente hay algunos casos extremos sobre el ancho de los caracteres y la superposición con los que no estoy tratando correctamente. Esto es principalmente una prueba de concepto en este momento.

¿Qué hay de renderizar el texto usando el atlas de caracteres y luego volver a renderizarlo en el fondo como un bloque de texto mientras está inactivo? Si los dos dan como resultado la misma imagen, puede descartar el texto combinado y volver al atlas. Al dividir cadenas de texto en segundo plano, es posible saber qué cadenas de texto están ligadas.

La parte complicada de esto es que la interpretación de una ligadura depende no solo de los caracteres reemplazados por la ligadura, sino también de su contexto. Por ejemplo, '=== 1' debería representar los tres signos iguales como una ligadura, pero '====' debería representar los mismos tres signos iguales como caracteres separados. No hay límite en el tamaño de este contexto, por lo que sería difícil y probablemente propenso a errores determinar las reglas de cuándo se representa una ligadura solo a partir de su salida.

Un enfoque más confiable (pero menos portátil) es tener las sugerencias sobre los rangos de ligadura provistas por una función separada que conoce los metadatos de la fuente. Luego, todo, excepto los rangos proporcionados por la función externa, se pueden representar usando el atlas, mientras que los grupos dados podrían usar un enfoque como el anterior. Determinar las ubicaciones de las sustituciones dada una línea de texto debería ser bastante rápido, pero tiene algunos de los problemas que detallé anteriormente (principalmente la velocidad / confiabilidad para encontrar la fuente correcta en la inicialización y la complejidad del procesamiento de alternativas contextuales OpenType).

¿Sería razonable tener una configuración para habilitar ligaduras, que escribe
una línea completa a la vez a la terminal? Parece que esto
garantizar una representación correcta, y el impacto en el rendimiento sería una opción para
gente que se preocupa más por las ligaduras que por la velocidad.

El domingo 22 de abril de 2018 a las 16:21, Jeff Principe [email protected] escribió:

La parte complicada es que la interpretación de una ligadura depende
no solo en los caracteres reemplazados por la ligadura sino también en su contexto.
Por ejemplo, '=== 1' debería representar los tres signos iguales como una ligadura pero
'====' debería representar los mismos tres signos iguales como caracteres separados.
No hay límite en la extensión de este contexto, por lo que sería difícil y
probablemente propenso a errores para determinar las reglas de cuando se renderiza una ligadura
solo por su salida.

Un enfoque más confiable (pero menos portátil) es tener las pistas sobre
rangos de ligadura proporcionados por una función separada que conoce la fuente
metadatos. Entonces todo menos los rangos proporcionados por la función externa
se pueden representar usando el atlas, mientras que los grupos dados podrían usar un
enfoque como el de arriba. Determinar la ubicación de las sustituciones
dada una línea de texto debería ser bastante rápido, pero tiene algunos de los problemas que
detallado anteriormente (principalmente velocidad / confiabilidad de encontrar la fuente correcta en
inicialización y complejidad del procesamiento de alternativas contextuales OpenType).

-
Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/xtermjs/xterm.js/issues/958#issuecomment-383420281 ,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/AAKyryMlayIQijY32GpWBmpvCUi13Wfbks5trRBigaJpZM4PRej6
.

@princjef Wow, tus ediciones son tan fáciles de seguir y parece que xterm puede admitir ligaduras con el renderizador. El truco consiste simplemente en descubrir cómo trazar las reglas. Eso me da esperanza.

@princjef gran investigación!

No hay forma de que pueda encontrar los datos de la fuente usando las API del navegador, por lo que esto no funcionará como una característica directa de xterm.js, sino más probablemente como un paquete / extensión separado con un gancho expuesto por xterm.js

@princjef Veo que el soporte de ligadura eventual vive como:

  • some-magical-package : Un módulo de nodo nativo extrae información de fuentes nativas, mapeando cadenas de fuentes web a los archivos si es posible. Esto podría hacerse en AsyncWorker para reducir el impacto en el rendimiento. No es gran cosa si esto se hace con pereza y en el primer lanzamiento se necesitan varios segundos para escanear y actualizar.
  • xtermjs/xterm-ligature-support : Un complemento que depende del nodo y usa some-magical-package para obtener y almacenar en caché la información de la fuente. Este complemento podría realizar un escaneo siempre que se detecten fuentes no reconocidas en el directorio de fuentes y desalojar las fuentes cuando se eliminen. Espero algo como esto como API aproximada:

    /** Returns a list of characters to be drawn together */
    export function getLigatures(fontFamily: string): string[] { ... }
    

Hay ciertas ligaduras que no tienen sentido en una terminal, incluso si la fuente lo admite (por ejemplo, li)

@mofux ¿ No estoy seguro de que debamos preocuparnos por esto? Si el usuario solicita ligaduras, ¿no deberíamos renderizarlas todas?

Agregar soporte para dibujar y borrar un carácter que abarca varias celdas es muy difícil de implementar con nuestro enfoque actual de renderizado basado en un solo carácter (CharAtlas).

@mofux Deberíamos poder agregar fácilmente una función para dibujar un conjunto de caracteres adyacentes juntos.

@princjef : No he realizado ninguna evaluación comparativa, pero apuesto a que esto no será bueno para el rendimiento.

@wavebeem : ¿Sería razonable tener una configuración para habilitar las ligaduras, que escribe una línea completa a la vez en la terminal?

Espero que anule casi por completo las mejoras de rendimiento que vienen con el uso del lienzo. También quiero mantener el número de opciones al mínimo, deberíamos intentar llegar a un lugar donde las ligaduras simplemente funcionen cuando se incluye un complemento para agregar soporte.

También en lo que respecta al rendimiento, es probable que esté trabajando para agregar una opción de renderizado de DOM de respaldo en los próximos meses, ya que hay demasiadas cosas que pueden salir mal con la compatibilidad con GPU en Chromium. Consulte https://github.com/xtermjs/xterm.js/issues/1360. Las ligaduras funcionarán fuera de la caja en este modo.

¿Qué hay de renderizar el texto usando el atlas de caracteres y luego volver a renderizarlo en el fondo como un bloque de texto mientras está inactivo? Si los dos dan como resultado la misma imagen, puede descartar el texto combinado y volver al atlas.

@ j-f1 esto es más difícil de lo que parece. Incluso si los caracteres se representan de la misma manera, el segundo será diferente ya que el espaciado en el atlas de caracteres es diferente (los caracteres siempre se dibujan en un número redondo). Necesitaríamos hacer mucho más renderizado para que esto funcione y muchos píxeles diferentes, lo cual es caro.

@Tyriar Creo que el diseño general que has descrito tiene sentido. _Puede_ ser capaces de salirse con la suya con algo que no dependa del código nativo para encontrar las fuentes en some-magical-package , pero definitivamente dependerá de la plataforma / sistema de archivos. Empecé a jugar analizando las sustituciones alternativas contextuales, pero es difícil decir cuánto más se necesitará para hacerlo bien.

También creo que acabaremos necesitando una interfaz ligeramente diferente a some-magical-package :

export function getSubstitutionRanges(fontFamily: string, text: string): Promise<[number, number][]>;

Las reglas para determinar las ligaduras en sí mismas son complicadas y están muy arraigadas en la fuente misma. En lugar de pasar los datos de la fuente en sí y poner la carga de interpretarlos en xterm.js, dejaría eso a la otra biblioteca y le diría a xterm.js qué caracteres deben procesarse juntos. Los aspectos de mirar hacia adelante y hacia atrás del contexto también complican el análisis. Por ejemplo, '===' se asigna a una ligadura, pero no si va seguido de otro signo igual.

Otra nota sobre el concepto de rangos de sustitución: no hay una delimitación clara de los límites de una sola ligadura de lo que puedo decir (al menos cuando se usan alternativas contextuales). Solo hay secuencias de sustituciones aplicadas a caracteres individuales. Encontré algunos trucos para averiguar los límites si tiene ligaduras consecutivas, pero probablemente no sea infalible. Probablemente me equivocaría al tratar accidentalmente dos ligaduras como una en lugar de dividirlas accidentalmente, ya que aún deberían renderizarse correctamente si se renderizan todas juntas como un solo grupo. El único problema real es aplicarle estilos heterogéneos.

El único problema real es aplicarle estilos heterogéneos.

Simplemente no lo hagas. Pase cada cadena de estilo continuo a la función por separado. Es posible que pueda hacer una excepción para el texto subrayado si el subrayado se dibuja por separado.

Es posible que podamos salirse con la nuestra con algo que no dependa del código nativo

👍

Las reglas para determinar las ligaduras en sí mismas son complicadas y están muy arraigadas en la fuente misma. En lugar de pasar los datos de la fuente en sí y poner la carga de interpretarlos en xterm.js, dejaría eso a la otra biblioteca y le diría a xterm.js qué caracteres deben procesarse juntos.

@princjef esto suena aún mejor, cuanto menos tenga que hacer xterm.js en esta área, mejor.

El único problema real es aplicarle estilos heterogéneos.

No creo que nada más intente hacer esto, solo deberíamos agregar ligaduras para el texto que usa el mismo estilo.

Esto parece factible en el lado de la fuente. Tengo un código que analiza con éxito todas las ligaduras de Fira Code y proporciona los rangos correctos para que los caracteres se combinen. Si las personas tienen una o dos fuentes más para las que buscan soporte, puedo intentar verificarlas también. Hasta ahora, solo he implementado los tipos de sustitución que necesitaba para Fira Code, por lo que sería bienvenida alguna variedad para ejercer los otros tipos de sustitución.

Todavía necesito averiguar la parte de búsqueda de fuentes. Me enfocaré en eso a continuación. Hay algunos paquetes, pero todos parecen tener errores o estar mal mantenidos.

@princjef Si desea verificar otras fuentes, estoy usando Iosevka .

De acuerdo, he creado un paquete llamado font-ligatures (también conocido como some-magical-package ) y algunos paquetes asociados para que podamos encontrar de manera eficiente la fuente correcta y luego averiguar dónde están las ligaduras para una entrada de texto determinada.

Pasé algún tiempo optimizando el proceso de búsqueda de la fuente. En Surface Pro 4 con ~ 150 fuentes ttf / otf, puedo obtener los metadatos de fuente para todos ellos en 300-400ms. En su mayoría está vinculado a E / S y se puede patear al fondo durante los primeros ciclos de renderizado mientras se carga, pero debe ser lo suficientemente rápido como para cargarse cuando se inicia un pty y escupe algo de texto. Una vez que está cargado, podemos activar un renderizado para actualizar cualquier texto que ya esté presente. Esto se puede repetir cada vez que cambia la fuente o podemos almacenar en caché la lista completa la primera vez (busco la lista completa al principio de todos modos).

En cuanto al mapeo de ligaduras en sí, la biblioteca toma una cadena y devuelve metadatos sobre las ligaduras de fuentes, incluidos los grupos de caracteres que deben renderizarse juntos. El CI incluye pruebas para cada ligadura en Fira Code, Iosevka y Monoid, por lo que estoy razonablemente seguro de que realiza el procesamiento correctamente para los tipos de sustitución que realiza (aunque estoy seguro de que hay algunas fuentes que usan otros tipos que No lo he implementado).

Sin embargo, no he dedicado tiempo a optimizar / ajustar el análisis de ligaduras. Hice algunas pruebas rápidas y parece que el análisis de ligaduras toma de 2 a 20 ms para una cadena de longitud moderada (lea: 1 línea). Todavía hay mucho espacio para optimizar, así que no estoy demasiado preocupado en este momento. Principalmente quería sacar esto para demostrar la interfaz y dejar que la gente pateara los neumáticos si lo deseaba.

¡Se ve muy bien @princjef! ¿Qué opinas acerca de agregar pruebas a Fira Code por 0xc0ffee , 0x1234 y 17x32 ? (El x convierte en un signo de tiempo en esos)

@princjef ¡increíble!

Hice algunas pruebas rápidas y parece que el análisis de ligaduras lleva de 2 a 20 ms para una cadena de longitud moderada (lea: 1 línea)

¿Puede señalarme algunos de los códigos críticos que verifican esto?

@ j-f1 Sí, esos también funcionan: https://github.com/princjef/font-ligatures/blob/master/src/index.spec.ts#L136 -L137

@Tyriar Acabo de agregar un punto de referencia básico con el que puedes jugar. el patrón de llamada se parece a node bench/lines.js <font-name> <input-text> [iterations] . También puede pasar una cadena de varias líneas o expandir un archivo de entrada para el texto y pasará por las líneas para tratar de evitar que las optimizaciones poco realistas ejecuten exactamente la misma entrada repetidamente.

Mientras escribía eso, noté que incluso cuando uso varias líneas de entrada diferentes, todavía experimenta un aumento significativo del rendimiento después de la primera ejecución. Para entradas de ~ 10 caracteres, veo promedios de una fracción de milisegundo para Iosevka y un poco más de medio milisegundo para Fira Code. O estoy golpeando un caso especial o Turbofan está funcionando, es mágico. Todavía no es lo suficientemente eficiente como para usarlo tal como está, pero comenzaré a enfocarme en las optimizaciones de rendimiento a continuación (en ese punto probablemente también agregaré un mejor punto de referencia para tener una idea de las mejoras).

Un par de notas:

  • Debido a la forma en que funcionan los reemplazos, esperaría que el tiempo de ejecución escale linealmente con el tamaño de la entrada, aunque no lo he verificado
  • Debido a la cantidad de ligaduras y la forma en que funcionan los reemplazos, Fira Code es mucho más intensivo para analizar que Iosevka o Monoid. Regularmente veo que se necesita de 5 a 10 veces más tiempo para hacer Fira Code que Iosevka.
  • Las fuentes sin ligaduras se ejecutan mucho más rápido y se pueden optimizar aún más. Si no hay alternativas contextuales en la fuente, puedo hacer una salida rápida con un conjunto de resultados vacío (o simplemente podemos omitir la llamada en un nivel superior).

Comencé a rastrear el aspecto del rendimiento en un problema en el paquete que creé (https://github.com/princjef/font-ligatures/issues/2). Aquí están los números iniciales copiados de allí para algunas configuraciones (todos los números son tiempos en ms). Las primeras cinco columnas de números son por línea de entrada y las dos últimas son por carácter. La penúltima columna es a la que estoy prestando más atención. Estoy disparando durante ~ 0.5 microsegundos por carácter (0.0005 en milisegundos):

NOMBRE | AVG | STDEV | 5% | 50% | 95% | AVG (CHAR) | STDEV (CHAR)
----------------------- | ------- | --------- | ------ | -------- | ------- | ------------- | ----------------
Código Fira: code.txt | 5,9570 | 12,6951 | 0,5270 | 5,1020 | 12,2330 | 0,1443531 | 0.2091743
Código Fira: noLigatures.txt | 12,1932 | 3,4402 | 8.1420 | 12,1205 | 15,5900 | 0,1321094 | 0.0334362
Iosevka: code.txt | 0,5571 | 1,4722 | 0,0485 | 0,3215 | 1,6155 | 0,0135005 | 0.0333483
Iosevka: noLigatures.txt | 0,7476 | 0,4230 | 0,4365 | 0,6030 | 1,7725 | 0,0080998 | 0,0044501
Monoid: code.txt | 0,8896 | 1,6637 | 0,0910 | 0,6625 | 1,9225 | 0,0215566 | 0.0482166
Monoide: noLigatures.txt | 1,6661 | 0,6935 | 1.0695 | 1,4450 | 2,6910 | 0,0180521 | 0,0071922
Ubuntu Mono: code.txt | 0,0402 | 0,3935 | 0,0080 | 0,0220 | 0,0605 | 0.0009735 | 0,0090228
Ubuntu Mono: noLigatures.txt | 0,0356 | 0,0644 | 0,0120 | 0,0280 | 0,0805 | 0,0003858 | 0.0006891

Ahora que hay buenos datos de referencia, tendremos una mejor idea de las ganancias obtenidas con cada ajuste de rendimiento.

@Tyriar , ¿tiene alguna preferencia sobre dónde vive el paquete xterm-ligature-support y cómo llega allí?

Parece que estás pensando que debería incluirse en la organización xtermjs (lo que me parece razonable), pero no tengo la capacidad de crear / enviar a un repositorio en la organización. ¿Preferiría que lo pusiera en un repositorio debajo de mi usuario que se migra a la organización o desea crear un repositorio de stub al que pueda enviar un PR?

Desde una perspectiva de revisión, tiene sentido finalizar el # 1460 primero, así que no hay prisa, pero quiero averiguar dónde volcar el código una vez que esté listo.

@princjef Creé https://github.com/xtermjs/xterm-ligature-support y te di acceso de administrador. Supongo que has visto cómo funcionan los otros complementos, pero este será el primer complemento externo oficial. Entonces, use los complementos internos y https://github.com/CoderPad/xterm-webfont como referencia para la implementación implementation

Veré las relaciones públicas pronto 👍

Publicado una actualización en el repositorio de vscode en este https://github.com/microsoft/vscode/issues/34103 , aquí está el trabajo restante antes de que podamos llamar a esto cerrado en xterm.js:

  • Integre xtermjs / xterm-addon-ligatures en el repositorio xtermjs / xterm.js , esto permitirá la publicación automatizada y garantizará que las pruebas continúen pasando
  • Conecta ligaduras a la demostración
  • Configure algunas pruebas de titiritero que verifiquen en todos los renderizadores (dom, canvas, webgl) que las ligaduras funcionan
  • Reduzca las dependencias tanto como sea posible

¡Gracias por todo el trabajo duro aquí a todos! 😄 👍

Si puedo preguntar, @Tyriar , ¿hay algún plan para la compatibilidad con el navegador web?

También vi que esto podría funcionar en el navegador, pero sería muy lento. Si puedo preguntar, ¿qué tan lenta fue esta versión que funcionó en el navegador?

¡Gracias!

@ torch2424 No creo que sea posible con la forma en que funcionan los renderizadores, ya que el soporte de ligaduras se basa en analizar el archivo de fuente (sin una codificación fija de qué ligaduras están disponibles proporcionadas por el usuario).

@Tyriar ¡ Gracias por la rápida respuesta!

Eso es lamentable, pero fue más agradable tenerlo. Hemos estado considerando una versión electrónica, así que tal vez la tengamos como característica incluida 😄 ¡Gracias!

Hmm, creo que debería ser posible, ya sea utilizando una fuente web y cargando los mismos archivos de fuentes (urgh) en dominios JS para extraer los datos de ligadura. No estoy seguro de si esto es factible / vale la pena hacerlo de esta manera, ya que la extracción de la ligadura es una abolladura bastante grande en el rendimiento. No estoy seguro sobre el uso de mem, un archivo de fuente puede ser bastante grande, ¿tal vez @princjef tiene aquí algunos números sobre el comportamiento en tiempo de ejecución?

Ha pasado un tiempo desde que lo investigué, pero lo que recuerdo es que no había API integradas para extraer información de fuentes sin procesar en el navegador, incluso para fuentes web.

Si tuviera que cargar manualmente su propia fuente web desde un archivo e inyectar por separado el contenido del mismo archivo en el código para analizar ligaduras, teóricamente es posible sin tener que renunciar a las optimizaciones de almacenamiento en caché de glifos en el renderizador. Dicho esto, el complemento existente no está diseñado con ese caso de uso en mente porque requiere más coordinación y cableado manual que el caso sin navegador.

No estoy seguro de si esto es factible / vale la pena hacerlo de esta manera, ya que la extracción de la ligadura es una abolladura bastante grande en el rendimiento. No estoy seguro sobre el uso de mem, un archivo de fuente puede ser bastante grande

Esto definitivamente puede ser un problema para ciertas fuentes. El paquete de procesamiento de ligaduras está muy optimizado para la eficiencia de búsqueda / detección, lo que por ahora tiene el costo de tiempos de carga más largos y consumo de memoria. Varía sustancialmente de una fuente a otra, pero es una buena consideración a tener en cuenta.

Incluso si fuera posible extraer información de ligaduras, la API web usa puntos de código de texto / caracteres, mientras que las ligaduras dentro de la fuente usan índices de glifos específicos de la fuente que no se pueden pasar directamente a las API web para dibujar.

@princjef Gracias por el aviso, esto suena demasiado engorroso, en mi humilde opinión no vale la pena por el beneficio que da después.

@khaledhosny La idea era más sobre obtener la información de ligadura de las fuentes en JS mientras se trabaja con puntos de código y dejar que el renderizador de fuentes del navegador haga las cosas de bajo nivel (dado que usa las mismas fuentes). No estoy seguro de si la extracción de glifos y la propia representación serían posibles únicamente en JS (jajaja, ¿un renderizador de fuentes basado en JS? Incluso si esto fuera factible, en mi humilde opinión, tendría un rendimiento realmente malo).

Actualización sobre esto, acabo de fusionar el complemento de ligaduras en la base de código (https://github.com/xtermjs/xterm.js/pull/2847), aún puede estar un poco roto, pero es difícil saberlo sin la configuración de las pruebas de integración ( https://github.com/xtermjs/xterm.js/issues/2896).

Actualmente, el complemento se ejecuta solo en un navegador + tiempo de ejecución de nodo (es decir, electron), se me ocurrió una propuesta que espero que funcione solo en el navegador, lo que nos permitiría eliminar los departamentos de nodos y llevar esto a VS Code (https: / /github.com/microsoft/vscode/issues/34103). Está etiquetado con ayuda necesaria si alguien quiere darle una oportunidad https://github.com/xtermjs/xterm.js/issues/2897.

Deberíamos considerar el uso de Font Access API (actualmente en prueba de origen) para el complemento de ligaduras.

Estoy usando ttyd que comparte terminal a través de la web y usa xterm.js. como puede ver en la imagen de abajo, los iconos no están cargados correctamente. son visibles en el terminal original. pero en la web faltan.

image

@UziTech oh wow, ¡se ve increíble! Creo que cualquier trabajo que se realice en esta área debería ser prospectivo para que podamos aprovecharlo con la API de acceso a fuentes.

@UziTech @Tyriar @princjef
Creo que el código para la API de acceso a fuentes se puede poner en paquetes font-ligatures .
Después de detectar si el proceso está en el navegador o en el nodo / electrón, puede decidir si llamar a la API de acceso a la fuente o usar el método actual.

Creé una prueba de concepto pirata y la ejecuté en la demostración en mi bifurcación (sucursal localFonts)
Screenshot 2021-01-17 at 18 39 27

Puede probarlo después de habilitar #font-access en chrome://flags (debe actualizar una vez después de permitir el acceso a las fuentes)

Puedo intentar abrir pr's si te parece bien.

Después de detectar si el proceso está en el navegador o en el nodo / electrón, puede decidir si llamar a la API de acceso a la fuente o usar el método actual.

Terminaremos teniendo problemas con esta solución, ya que los proyectos que son solo web tendrán problemas para agrupar los departamentos de nodos. No tengo una respuesta para eso, pero también creo que deberíamos cambiar los valores predeterminados (¿eventualmente?) Y el acceso predeterminado a la fuente si la detección de características tiene éxito, de lo contrario, retroceder.

¡También un gran trabajo para que funcione! Eso es asombroso 😍

Podemos require después de la detección de características solo si es necesario.
Y los proyectos dependientes solo de la web pueden marcarlos como externos durante la agrupación.

Podemos tener la API de acceso a fuentes como predeterminada una vez que esté disponible en todos los navegadores, supongo.

👍 Es posible que esté pensando demasiado en la preocupación del paquete, ya que mencionas que hay soluciones. Espero que desaprovechemos / eliminemos gradualmente la opción Electron una vez que el acceso a la fuente se active en Electron de todos modos.

@Tyriar, ¿podemos obtener actualización en font-finder?

@UziTech [email protected] debería tener eso, he creado un recordatorio para actualizar la versión 4.10 https://github.com/xtermjs/xterm.js/issues/3220

Abrí un pr princjef / font-ligatures # 22 como primer paso para hacer esto

¿Fue útil esta página
0 / 5 - 0 calificaciones