Terminal: Solicitação de recurso: suporte a gráficos sixel

Criado em 7 mai. 2019  ·  58Comentários  ·  Fonte: microsoft/terminal

Gostaria de ver suporte Sixel no Terminal, este é o padrão usado para mostrar gráficos no console.

Sixel faz parte da especificação DEC original para fazer gráficos em terminais e foi re-popularizado nos últimos anos para fazer gráficos na linha de comando, em particular por Pythonistas fazendo ciência de dados.

A biblioteca libsixel fornece um codificador, mas também é uma ótima introdução ao assunto (melhor que a página da Wikipedia):

https://github.com/saitoha/libsixel

Area-Output Area-Rendering Issue-Feature Product-Conpty Product-Terminal

Comentários muito úteis

Oh. Sixel é uma coisa muito legal.

Decidi que preciso disso. PRECISAR.

Todos 58 comentários

Ao implementar o Sixel, é importante testar com imagens que contenham transparência.
A transparência pode ser obtida desenhando pixels de cores diferentes, mas não desenhando alguns pixels em nenhuma das cores Sixel, deixando a cor de fundo como ela.
Eu acredito que esta é a única maneira de desenhar Sixels não retangulares corretamente, e seria especialmente bom com a transparência acrílica de fundo no novo Terminal do Windows.

Testando usando WSL com Ubuntu, por exemplo, em mlterm tais imagens são renderizadas corretamente como tendo uma máscara de transparência e a cor de fundo é mantida, enquanto em xterm -ti vt340, pixels intocados são desenhados em preto, mesmo que o fundo seja branco, o que parece implicam que eles renderizam sixels em um bitmap de memória inicializado como preto sem máscara de transparência ou alfa antes de exibi-los na janela do terminal.

Oh. Sixel é uma coisa muito legal.

Decidi que preciso disso. PRECISAR.

Terei todo o gosto em rever um PR :)

Peguei a entrevista do Build 2019 hoje que mencionou esse pedido. Eu ainda sustento que o Xorg no sixel está errado . Então _muito muito errado_.

A demo ffmpeg-sixel "Steve Ballmer Sells CS50 " nunca se cansa. Tenho que dizer que é um pouco decepcionante o vídeo não ter som (o som realmente faz o vídeo ). Os consoles já têm som, naturalmente. Eles apitam totalmente. Conjunto de precedentes. O que realmente _precisamos_ é uma nova sequência CSI para os clipes de opus intercalados com os quadros, amirite?

Ken, eu realmente mereço isso por mencionar Sixels ;)


De: therealkenc [email protected]
Enviado: quarta-feira, 8 de maio de 2019 16:31:31
Para: Microsoft/Terminal
CC: Assinado
Assunto: Re: [microsoft/Terminal] Suporte a gráficos Sixel (#448)

Capturado o Build 2019 https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmybuild.techcommunity.microsoft.com%2Fhome%23top-anchor&data=01%7C01%7Cduhowett%40microsoft.com %7C81f48be19f374665cd3408d6d40d4dc6%7C72f988bf86f141af91ab2d7cd011db47%7C1&sdata=i8rfPCaN%2FxqdF%2F4qRtdN2Py4%2BVRlbPgpwJWtPSGGHc%3D&reservado=0 entrevista hoje que menciona esta solicitação. Eu ainda sustento que o Xorg no sixel está errado https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fmicrosoft%2FWSL%2Fissues%2F1099%23issuecomment-248513013&data=01 %7C01%7Cduhowett%40microsoft.com%7C81f48be19f374665cd3408d6d40d4dc6%7C72f988bf86f141af91ab2d7cd011db47%7C1&sdata=J%2BwCnn0z70FkI9lDcus1nMX&reservedcKz3D0ArL%2B . Muito muito errado.

O ffmpeg-sixel https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fsaitoha%2FFFmpeg-SIXEL&data=01%7C01%7Cduhowett%40microsoft.com%7C81f48be19f374665cd3408d6d40d4dc6%7C72f988bf86f141af91ab2d7cd011db47 %7C1&sdata=G%2F9mvw1EdADkwChSbHZ%2FI54k9xvXagV%2FxD9VbJtyw7g%3D&reserved=0 Demonstração "Steve Ballmer vende CS50" https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.youtube.com% 2Fwatch% 3Fv% 3D7z6lo4aq6zc% 26feature% 3Dyoutu.be & data = 01% 7C01% 7Cduhowett% 40microsoft.com% 7C81f48be19f374665cd3408d6d40d4dc6% 7C72f988bf86f141af91ab2d7cd011db47% 7C1 & sdata = 6IVwBHs6% 2F43rXdk6GabiSUpTFS86xUGB6bubfkS3ea0% 3D & reservados = 0 nunca fica tho cansado. Tenho que dizer, é um pouco decepcionante o vídeo não ter som (o som realmente faz o vídeo https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv % & 3DEl2mr5aS8y0 dados = 01% 7C01% 7Cduhowett% 40microsoft.com% 7C81f48be19f374665cd3408d6d40d4dc6% 7C72f988bf86f141af91ab2d7cd011db47% 7C1 & sdata = Mm1ICN5KcgrP5YmdAZsUCzUKbVQDtxFE1qAEpkhKiZk% 3D & reservados = 0 ). Os consoles já têm som, naturalmente. Eles apitam totalmente. Conjunto de precedentes. O que realmente precisamos é de uma nova sequência CSI https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FANSI_escape_code%23CSI_sequences&data=01%7C01%7Cduhowett% 40microsoft.com% 7C81f48be19f374665cd3408d6d40d4dc6% 7C72f988bf86f141af91ab2d7cd011db47% 7C1 & sdata = 29pJq5661TXtnn2huLyUMgebTyYMEhTKXpAm19jzqHU% 3D & reservados = 0 para a obra https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FOpus_ (audio_format) & dados = 01% 7C01% 7Cduhowett% 40microsoft.com% 7C81f48be19f374665cd3408d6d40d4dc6% 7C72f988bf86f141af91ab2d7cd011db47% 7C1 & sdata = XOq6Acz4% 2B7gQeTKQBQ2fYJPnoLvx6vUjmLRhgOX1eDo% 3D & reservados = 0 clipes intercalados com os quadros, amirite?


Você está recebendo isso porque está inscrito neste tópico.
Responda a este e-mail diretamente, visualize-o no GitHub https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fmicrosoft%2FTerminal%2Fissues%2F448%23issuecomment-490688164&data=01 % 7C01% 7Cduhowett% 40microsoft.com% 7C81f48be19f374665cd3408d6d40d4dc6% 7C72f988bf86f141af91ab2d7cd011db47% 7C1 & sdata = pnXPvsuGF7l5mQfU2htzFwJnqZjEuW4zNuh1HaBJnKM% 3D & reservados = 0 , ou cortar o fio https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub. com% 2Fnotifications% 2Funsubscribe-auth% 2FADNHLGXQOYKINZMIBKTB4LTPUNPFHANCNFSM4HLENFOQ & data = 01% 7C01% 7Cduhowett% 40microsoft.com% 7C81f48be19f374665cd3408d6d40d4dc6% 7C72f988bf86f141af91ab2d7cd011db47% 7C1 & sdata =% 2F4pMmm7bvPa% 2BbFmE1gyN8% 2BoTZDKJyRksBrkJpDh% 2BLug% 3D & reservados = 0 .

Relacionado: #120

Precisar.

needthis

LOL Eu estava assistindo a transmissão e pensei comigo mesmo "aqui está meu chefe me designando um trabalho ao vivo na frente de uma platéia de estúdio".

Por favor, faça disso uma prioridade para a v1.0!

Animações 3D podem ser v1.5 😛

Oh meu Deus

Aprovando esse pedido, Sixels seria uma coisa incrível de se ter no Terminal.

Este fim de semana eu terminei de implementar o suporte de leitura sixel para minha biblioteca TUI baseada em Java licenciada pelo MIT, e foi surpreendentemente simples. O código para converter uma string de dados sixel em uma imagem de bitmap está aqui , e o código do cliente para a classe Sixel está aqui .

Eu fiz muito pouco para o desempenho no decodificador. Mas ao usar o backend Swing, o desempenho ainda é bom, como visto aqui . (A imagem da cobra parece ruim apenas porque byzanz usou uma paleta ruim para criar o gif de demonstração.) Fiquei um pouco surpreso com a rapidez com que ela se formou. É muito justo dizer que a parte "decodificar sixel em bitmap" é a parte mais fácil, a parte mais difícil é "colocar dados de imagem em uma célula de texto e, quando isso estiver presente, decodifique a imagem na tela em vez do caractere".

Só quero mencioná-lo a outras pessoas interessadas em suporte de terminal para sixel e esperando que isso possa ajudá-lo.

Eu votarei se outra pessoa escrever um cliente de notebook Jupyter;)

Já temos um exemplo de suporte Sixel em mintty que está escrito em C (vice java). A única coisa necessária é uma refatoração para C++ (pelo menos para suporte inicial). Ainda é sempre bom ver como tem sido implementado em outros projetos.

Já temos um exemplo de suporte Sixel em mintty que está escrito em C (vice java). A única coisa necessária é uma refatoração para C++ (pelo menos para suporte inicial). Ainda é sempre bom ver como tem sido implementado em outros projetos.

Algum problema com a licença do mintty (GPLv3 ou posterior)?

https://github.com/mintty/mintty/blob/master/LICENSE

A partir desse link:

O código Sixel (sixel.c) é relicenciado sob GPL como mintty com a
permissão de seu autor (kmiya@culti)

Se você transliterar esse código exato para C++, o trabalho derivado precisaria ser licenciado GPLv3 ou posterior, de acordo com seus termos, ou não ser distribuído. (Pode-se também perguntar a kmiya @culti se eles estão dispostos a oferecer sixel.c sob uma licença diferente, ou se já esteve disponível sob outra coisa, encontre uma cópia dessa fonte.)

Eu não sei o que é aceitável ou não para inclusão no Windows Terminal - minha rápida olhada no Windows Terminal diz que é licenciado pelo MIT, então dependendo de como ele está vinculado/carregado usando um descendente direto do GPLv3 + sixel.c do mintty pode levar a um problema de licença.

De qualquer forma, desculpe estar atrapalhando o projeto de outra pessoa aqui, voltando para a caverna agora...

Existe um widget de emulador de terminal humilde e capaz de sixel escrito em C/C++ para Windows/Linux, e possui uma classe SixelRenderer que você pode usar (embora precise de alguma otimização) e possui uma licença BSD-3. Indiscutivelmente, sua maior desvantagem é que ele foi escrito para uma estrutura C++ específica. Ainda assim, o código IMO do SixelRenderer é traduzível com pouco esforço. (Eu sei disso porque sou seu autor. :))

https://github.com/ismail-yilmaz/upp-components/tree/master/CtrlLib/Terminal

Ao implementar o Sixel, é importante testar com imagens que contenham transparência.
A transparência pode ser obtida desenhando pixels de cores diferentes, mas não desenhando alguns pixels em nenhuma das cores Sixel, deixando a cor de fundo como ela.
Eu acredito que esta é a única maneira de desenhar Sixels não retangulares corretamente, e seria especialmente bom com a transparência acrílica de fundo no novo Terminal do Windows.

Testando usando WSL com Ubuntu, por exemplo, em mlterm tais imagens são renderizadas corretamente como tendo uma máscara de transparência e a cor de fundo é mantida, enquanto em xterm -ti vt340, pixels intocados são desenhados em preto, mesmo que o fundo seja branco, o que parece implicam que eles renderizam sixels em um bitmap de memória inicializado como preto sem máscara de transparência ou alfa antes de exibi-los na janela do terminal.

Hmm. o VT340 que estou na frente honra o parâmetro P2 no DCS P1 ; P2; P3; q sequência que inicia a sequência SIXEL. O Xterm, por outro lado, parece ignorá-lo. Mas se você usar a sequência de atributos raster ("Pan; Pad; Ph; Pv) e der a ela uma altura e largura, ela limpará o fundo para que você obtenha um pixel preto.

Eu estava pensando em fazer o teste gratuito do emulador ttwin e verificar como seu comportamento difere do VT340 e do Xterm atuando como um VT340.

Mas... +1 pela ideia de suportar o SIXEL em geral e +10 pela ideia de apresentar testes de compatibilidade.

Poderíamos adicionar suporte para o protocolo de imagens em linha iTerm2 quando estivermos lá... Pelo menos deve ser mais fácil de implementar, só precisa de um caminho para a imagem e faz tudo sozinho.

Uma dúvida que tenho com os dois sistemas é, o que acontece com o alinhamento? Se a largura ou a altura da imagem for um múltiplo da largura ou altura dos caracteres, tudo está ok, mas se não, um preenchimento deve ser adicionado apenas nos lados inferior e direito, ou a imagem deve ser centralizada adicionando preenchimento em todos os lados?

Ei, aqui estão alguns links relevantes para pesquisa:

Poderíamos adicionar suporte para o protocolo de imagens em linha iTerm2 quando estivermos lá... Pelo menos deve ser mais fácil de implementar, só precisa de um caminho para a imagem e faz tudo sozinho.

Isso provavelmente deveria ser uma tarefa diferente. Sixel e ReGIS são explicitamente para dados gráficos ou de caracteres em banda. Não estou dizendo que é uma má ideia, estou apenas dizendo que deveria ser tratado como um recurso diferente.

Uma dúvida que tenho com os dois sistemas é, o que acontece com o alinhamento? Se a largura ou a altura da imagem for um múltiplo da largura ou altura dos caracteres, tudo está ok, mas se não, um preenchimento deve ser adicionado apenas nos lados inferior e direito, ou a imagem deve ser centralizada adicionando preenchimento em todos os lados?

O alinhamento dos dados gráficos Sixel e ReGIS é descrito (mal) em vários manuais. As imagens Sixel são alinhadas nos limites das células dos caracteres. Se você quiser uma borda preta ao redor de uma imagem, você mesmo deve adicionar esses pixels pretos; não há nenhum conceito de margem ou preenchimento de HTML. Cada linha de dados sixel descreve uma faixa de seis pixels de altura. Se você estiver tentando alinhar dados de imagem sixel com caracteres de texto em um emulador de terminal, isso pode ser frustrante, pois o software que gera os dados sixel pode não saber quantos pixels de altura tem cada glifo de caractere. Se você tiver um xterm antigo à mão, poderá ver isso iniciando-o no modo vt340, especificando diferentes tamanhos de fonte (para fornecer diferentes tamanhos de células de caracteres) e, em seguida, imprimindo alguns dados sixel que tentam alinhar dados de imagem com texto dados. (Aqui está um arquivo de teste simples que parece correto quando digo ao servidor de fontes para usar 96DPI e especifico uma fonte de 15 pontos. Modificar o tamanho da fonte faz com que as imagens fiquem cada vez mais desalinhadas com o texto. https://gist.github. com/OhMeadhbh/3d63f8b8aa4080d4de40586ffff819de )

Os vt340s originais não tiveram esse problema porque (é claro) você não conseguiu especificar um tamanho de fonte ao ligar o terminal.

A outra coisa que você pode ver nessa imagem, que não está bem descrita na documentação do sixel, é que imprimir uma linha de dados do sixel estabelece uma "margem esquerda virtual" para os dados da imagem. Se você fizer o equivalente moral de um CR ou CRLF usando os caracteres '$' ou '-', a próxima linha será impressa em relação a essa margem esquerda virtual, não à margem esquerda real no lado esquerdo do terminal.

Espero que isto ajude.

Finalmente rolando de volta para ler isso. Desculpe a resposta tardia.

Testando usando WSL com Ubuntu, por exemplo, em mlterm tais imagens são renderizadas corretamente como tendo uma máscara de transparência e a cor de fundo é mantida, enquanto em xterm -ti vt340, pixels intocados são desenhados em preto, mesmo que o fundo seja branco, o que parece implicam que eles renderizam sixels em um bitmap de memória inicializado como preto sem máscara de transparência ou alfa antes de exibi-los na janela do terminal.

Não deve ser muito difícil oferecer suporte à transparência no xterm. Estive pesquisando no código por outros motivos. Temo que alguém, em algum lugar, esteja dependendo desse comportamento do Xterm, então recomendo colocá-lo atrás de um sinalizador de compatibilidade, que também deve ser direto. Mas depois há a questão do valor padrão. Qual deve ser o padrão? Preto ou transparente.

Sabemos o que os VT240, 241, 330 e 340 originais fizeram? Eu poderia sugerir tentar representar fielmente a experiência de um VT realcomo o comportamento padrão? Você pode testar isso imprimindo caracteres de espaço invertido e, em seguida, sobrepondo gráficos de seis camadas acima deles e vendo como os pixels não especificados de cor são renderizados.

Não sei se me importo muito com o padrão do terminal msft, desde que haja a capacidade de se comportar como o Xterm emulando um VT340. O código que escrevi para fazer loglines sobre ssh no terminal assume o comportamento "pixels não especificados são pretos" descrito acima. Eu teria que reescrever esse código se fizermos essa alteração.

Se você estiver tentando alinhar dados de imagem sixel com caracteres de texto em um emulador de terminal, isso pode ser frustrante, pois o software que gera os dados sixel pode não saber quantos pixels de altura tem cada glifo de caractere.

Os vt340s originais não tiveram esse problema porque (é claro) você não conseguiu especificar um tamanho de fonte ao ligar o terminal.

Existe alguma razão pela qual um emulador de terminal não poderia simplesmente dimensionar a imagem para corresponder exatamente ao comportamento dos terminais DEC originais? Portanto, se a altura da linha em um VT340 for de 20 pixels, uma imagem com 200 pixels de altura deverá cobrir exatamente 10 linhas, independentemente do tamanho da fonte. Essa me parece a única maneira de você permanecer razoavelmente compatível com o software legado, que é o objetivo de um emulador de terminal.

Eu posso entender querer estender esse comportamento para renderizar imagens em uma resolução mais alta, mas acho que essa deve ser uma extensão opcional (ou apenas usar um dos formatos proprietários existentes). Então, idealmente, eu gostaria que o padrão para o Sixel fosse o mais próximo possível do que você teria obtido em um terminal DEC real.

Ei, aqui estão alguns links relevantes para pesquisa:
"Noções básicas para um bom protocolo de imagem" no terminal-wg

O Sixel está quebrado porque não pode ser suportado pelo tmux com painéis lado a lado.

image

font-resize

Deu algum trabalho (na verdade, muito trabalho ), mas com o sixel pode-se executar quase todos os truques de "imagens em um terminal" que se pode imaginar:

Incluí algumas outras observações no segmento de protocolo "bom" referenciado que podem ser de interesse.

Se nada mais, sixel é um bom trampolim para trabalhar a infraestrutura do lado do terminal de imagens e texto mistos. Falando por experiência direta, o lado do terminal (armazenar/exibir imagens) é cerca de 1/4 tão difícil quanto o lado do multiplexador/aplicativo (tmux/mc et al).

sixels são de fato a solução ideal para gráficos em banda (por exemplo, sobre ssh): como eles são suportados por muitas ferramentas existentes, eles estão prontos para uso para fins práticos, como plotar problemas de sincronização de timestamp em movimento.

Conforme ilustrado por therealkenc e explicado por klamonte em 640292222 tudo pode ser tratado com seisels, mesmo imagens lado a lado, mas requer algum trabalho.

Um tempo atrás eu estava trabalhando com algumas outras pessoas em um modo de fallback para tmux, usando gráficos unicode avançados para representar imagens sixel em terminais que não suportam sixel.

É um pouco como a arte ANSII automatizada, aproveitando os caracteres de bloco especiais que estão presentes na maioria das fontes: essa representação unicode de cores equivalente pode ser substituída pelos sixels e depois substituída pela imagem sixel real (ou não!). Também resolveria o problema de manter todas as imagens sixel para rolar para trás, substituindo-as por espaços reservados unicode de baixa fidelidade (por ex para economizar memória) e ter espaços reservados para imagens sixel quando não puderem ser exibidas por qualquer motivo.

O código era de domínio público. Pode ser usado imediatamente como um primeiro passo para o suporte sixel:

  • detectar quando a sequência sixels é transmitida e, em seguida, calcular a substituição de texto unicode

  • exibir esta sequência unicode, que já é suportada pelo Windows Terminal

  • mais tarde, quando os sixels forem implementados, renderize no topo a sequência sixel.

Você estaria interessado?

BTW eu reconheço aqui meu familiar gnuplot x^2 sin e 10 sin(x) plots estou feliz por ter fornecido alguma inspiração 😄

Por favor.

@DHowett O acac350 é o primeiro passo para renderizar gráficos sixel? Estou recebendo solicitações de suporte sixel no Microsoft Terminal de pessoas que usam ssh e desejam visualizar diretórios de imagens usando meu programa lsix .

Sorte. Agora temos a capacidade de lidar com sequências DCS de entrada. Ainda não conectamos nenhum manipulador, mas ter a infraestrutura para isso foi muito importante. :sorrir:

Aqui estão algumas atualizações. Eu tenho um ramo de trabalho aqui . Uma captura de tela inicial se parece com isso:

image

Ao contrário do que eu pensava originalmente, a parte mais difícil de renderizar as imagens sixel é na verdade a camada de conpty. As imagens Sixel devem ser objetos inline. A renderização de imagens sixel depende do tamanho de renderização de um caractere. No entanto, devido à camada extra de conpty, na verdade não podemos obter o tamanho de renderização de um caractere ao processar sequências sixel. Isso soa muito abstrato e vago. Qualquer pessoa interessada nisso pode verificar minha filial e ver como é feito.

No geral, a camada conpty torna muito difícil lidar com a rolagem e o redimensionamento de imagens sixel. No meu branch funciona se você só precisar exibi-lo. Mas tanto a rolagem quanto o redimensionamento estão completamente quebrados.

Ainda não olhei, mas você pode usar o modo de passagem para implementar no próprio Terminal? Eu ainda o adicionaria no OpenConsole, mas parece que o compartilhamento de código não é possível. Como o Windows Terminal precisa ser desacoplado do OpenConsole em algum momento, é melhor simplesmente duplicar o código para ambos. Você também está se baseando nos seus PRs e no j4james para parâmetros? Isso provavelmente ajudaria também.

@WSLUser Obrigado pela atenção. Esta captura de tela é na verdade de cerca de um mês atrás, quando os parâmetros fantásticos PR do j4james nem existiam. Meu trabalho é inteiramente dentro do Windows Terminal, não no conhost. Mostrei esse PR para a equipe do Console internamente e fiz algum progresso desde então. Mas estou preso por causa do problema de conpty.

Sim, eu faria o rebase do master e adicionaria https://github.com/microsoft/terminal/pull/7578 e https://github.com/microsoft/terminal/pull/7799. A partir daí, talvez veja o que está faltando no ConPTY para o modo de passagem. Gostaria de saber se Mintty está usando passagem para o modo ConPTY.

Gostaria de saber se Mintty está usando passagem para o modo ConPTY.

Tenho certeza que mintty não está usando conpty 😜


O truque aqui com conpty é que o console (conpty) precisará saber sobre as células que são preenchidas com o conteúdo do sixel, para não limpar acidentalmente esse conteúdo do Terminal conectado. Talvez o conpty possa ser iluminado para ignorar a pintura de células com gráficos sizel e apenas assumir que o Terminal conectado deixará essas células em paz.

Isso pode atrapalhar algumas de nossas otimizações (como não podemos apagar linhas que têm dados sixel), mas pode ser um começo bom o suficiente

\

Talvez o conpty possa ser iluminado para ignorar a pintura de células com gráficos sizel e apenas assumir que o Terminal conectado deixará essas células em paz.

Este também era meu plano original, e pode ser a melhor solução com a arquitetura atual, mas há uma série de complicações.

  1. Como isso interagiria com o streaming DCS (para o qual acho que ainda não temos uma solução). Estou assumindo que precisaríamos de algum tipo de conceito de fluxo dividido que passasse o fluxo de bytes para conpty ao mesmo tempo em que é enviado para o buffer do host, mas parece que adicionaria muita sobrecarga desnecessária ao processo.
  2. Isso só funcionaria se você conhecesse o tamanho da célula de pixel do terminal conpty. Eu mencionei antes que acho que a melhor solução para o Sixel é combinar o tamanho da célula dos terminais VT originais e, se estivéssemos fazendo isso, isso não seria um problema. No entanto, até onde eu sei, nenhum outro emulador de terminal faz isso, então não funcionaria com mais ninguém.

O segundo problema que @j4james trouxe se torna ainda mais complicado com a consideração de fontes diferentes, tamanhos de fontes diferentes e redimensionamento de fontes. Então, geralmente, acho que há 3 aspectos da questão:

  • O primeiro conpty precisará saber sobre as células que são preenchidas com o conteúdo sixel, sem isso, o buffer de apoio no conpty e o buffer de desenho no WT estarão inevitavelmente fora de sincronia.
  • Para fazer isso, o conpty precisará saber o tamanho da célula do pixel no contexto do desenho, que é tratado pela camada de desenho no WT. Há uma enorme lacuna entre o conpty e o DXRenderer real, o que torna essa tarefa difícil.
  • Além disso, quando a fonte ou o tamanho da fonte muda, idealmente a imagem sixel deve mudar de forma correspondente.
  • E finalmente lide com outras coisas como painel, buffer alternativo, desenho diferencial, rolagem, etc.

O segundo problema que @j4james trouxe se torna ainda mais complicado com a consideração de fontes diferentes, tamanhos de fontes diferentes e redimensionamento de fontes. Então, geralmente, acho que há 3 aspectos da questão:

Só para ficar claro, meu ponto era que nada disso seria um problema se nós correspondermos exatamente ao comportamento de um VT340, então uma imagem de 10x20 pixels ocuparia exatamente uma célula de caractere, independentemente do tamanho da fonte. Só é um problema se quisermos igualar o comportamento de outros emuladores de terminal, e isso sempre pode ser uma opção que fica para depois. Ainda haveria complicações com essa abordagem, mas pessoalmente acho que elas são menos preocupantes.

Minha maior preocupação é que você parece estar ignorando o problema de streaming DCS, que espero que possa mudar fundamentalmente a arquitetura da solução. Os passos que eu gostaria de ver são: 1. Resolva #7316; 2. Acordar uma solução para o tamanho do pixel da célula; 3. Faça algo funcionar no conhost; 4. Uma vez que todas as complicações são resolvidas no conhost, só então considere como podemos fazer isso funcionar no conpty.

Desculpe por deixar o problema de streaming DCS. Na minha implementação atual, apenas armazeno a string inteira e a passo para o mecanismo. Isso introduz problemas de desempenho quando a sequência é maior. Mas pelo menos funciona. Portanto, meus comentários acima são amplamente baseados nisso.

Mas você está certo. O problema de streaming DCS é, na verdade, a principal prioridade se alguém quiser sujar as mãos nisso.

获取 Outlook para iOS https://aka.ms/o0ukef

Por discussão em https://github.com/microsoft/terminal/issues/57 , pensei que conpty não se importa com fontes?

wrt redimensionamento Acho que a maneira mais natural de fazer isso é "ancorar" a imagem em células de caracteres assim que a imagem chegar e recalcular o tamanho da imagem com base na geometria da âncora. Qualquer outra coisa causará inconsistência nas células de imagem versus caracteres.

@yatli Sim. Isso também é o que torna a questão complicada.

A imagem de 10 x 20 pixels ocuparia exatamente uma célula de caractere

Infelizmente, isso está errado, pelo menos para minha configuração de fonte atual.

Corrija-me se estiver errado, mas para exibição de imagem perfeita em pixels, acho que precisamos nos preocupar com as fontes.

@skyline75489 pls veja meu comentário atualizado sobre a "âncora"

A estrutura de dados da célula precisa ser atualizada como char | sixel anchor

A âncora sixel deve conter informações sobre:

  • Um ponteiro para o objeto de imagem
  • A região da célula char que ela ocupa, em números flutuantes (por exemplo, 5,2 linhas x 7,8 cols)

É uma boa ideia, mas os detalhes de implementação estavam me matando, devido à tradução extra na camada conpty. Para evitar enviar spam às pessoas com e-mail, sinta-se à vontade para me contatar no Teams @yatli se estiver interessado.

A imagem de 10 x 20 pixels ocuparia exatamente uma célula de caractere

Infelizmente, isso está errado, pelo menos para minha configuração de fonte atual.

O que estou sugerindo é que você faça isso acontecer. Se você criar uma imagem de 10x20 pixels e enviá-la em um terminal DEC VT320 real, ela terá exatamente um caractere (pelo menos no modo de 80 colunas). Então, se estamos tentando emular esse terminal, devemos fazer a mesma coisa. Se sua fonte atual for 30x60, você precisará aumentar a escala da imagem. Se sua fonte for menor, você reduz a escala da imagem.

Isso garante que você possa produzir uma imagem Sixel em qualquer tamanho de fonte e sempre obter o mesmo layout. Se você deseja que ela cubra uma determinada área da tela ou deseja desenhar uma borda em torno dela com caracteres de texto, você sabe exatamente quanto espaço a imagem ocupará.

Corrija-me se estiver errado, mas para exibição de imagem perfeita em pixels, acho que precisamos nos preocupar com as fontes.

É verdade que você não obterá imagens "pixel perfeitas" dessa maneira, mas não acho que esse deva ser o objetivo principal. Muitos computadores modernos têm telas de alto dpi, onde é rotina que as imagens sejam ampliadas, então não é como se este fosse um conceito estranho. E se quisermos manter o layout consistente quando o usuário alterar o tamanho da fonte, teremos que dimensionar a imagem em algum momento, então é melhor fazê-lo desde o início e obter todos os benefícios de uma imagem previsível Tamanho.

E, claro, o outro benefício de fazer as coisas dessa maneira é que isso pode ser implementado de maneira viável. Não vejo como você pode fazer o conpty funcionar se a área ocupada pela imagem for dependente do tamanho da fonte, que você não pode saber.

Não vou fingir que essa abordagem não terá desvantagens, mas acho que os aspectos positivos superam os negativos.

E se a fonte tiver uma proporção diferente de 10:20?

E se a fonte tiver uma proporção diferente de 10:20?

Posso sugerir a leitura desta longa - e um tanto "brutal" - discussão sobre os problemas gerais em relação às imagens inline em emuladores de terminal .

Pode dar-lhe a ideia geral.

Atenciosamente

E se a fonte tiver uma proporção diferente de 10:20?

A imagem pode estar um pouco esticada ou amassada, mas não acho que seja o fim do mundo.

Deixe-me demonstrar com um exemplo do mundo real. Imagine que sou um vilão de Bond e tenho um sistema de segurança antigo usando um VT340 como frontend. Agora, por causa do coronavírus, estou trancado e trabalhando em casa, então estou entrando no sistema remotamente com o Windows Terminal. Se correspondermos exatamente ao VT340, isso não é problema - o terminal se parece com isso:

image

Mas talvez eu prefira fontes com uma proporção estranha. Então vamos ver como ficaria com _Miriam Fixed_, que é mais larga que a maioria. A imagem de Bond agora parece um pouco esmagada, mas ele ainda é facilmente reconhecível.

image

A alternativa seria ir com uma imagem perfeita de pixel (não viável atualmente com conpty, mas vamos fingir por um segundo). Bond não parece mais esmagado, mas agora a imagem é apenas uma fração do tamanho que se esperava. E quanto maior a resolução do seu monitor, pior vai ficar.

image

Talvez seja uma questão de preferência pessoal, mas sei que definitivamente escolheria a opção 1 em vez da opção 2.

Observe também que não há motivo para não termos opções para ajustar o comportamento exato quando a proporção da fonte não for 1:2. Uma opção poderia ser centralizar a imagem dentro das células que ela deveria ocupar. Ou podemos expandir a imagem para cobrir toda a área, mas cortar as bordas que ultrapassam os limites. Qualquer uma dessas opções seria melhor do que uma renderização de pixel exata na minha opinião.

Talvez seja uma questão de preferência pessoal, mas sei que definitivamente escolheria a opção 1 em vez da opção 2.

Eu também, apenas seria melhor saber que a fonte tem uma proporção diferente, para que a imagem possa se ajustar e manter a correta.

Uma opção poderia ser centralizar a imagem dentro das células que ela deveria ocupar. Ou podemos expandir a imagem para cobrir toda a área, mas cortar as bordas que ultrapassam os limites

Acho melhor centralizá-los.

Talvez eu esteja interpretando mal este tópico. Estamos realmente falando sobre o terminal fingindo caracteres 10:20 para a imagem sixel? Acho que isso vai causar muitos problemas como a distorção do Bond. Fazer isso da maneira certa pode ser mais difícil, mas, na minha humilde opinião, um terminal moderno deve ser independente de fontes e deixar para os programadores de aplicativos lidar com seis e células de caracteres.

Usando seqüências de escape, um programa executado pelo usuário pode determinar o tamanho da célula de caracteres em pixels e decidir como lidar de forma inteligente com a distorção para esse aplicativo. O programa de visualização de imagens que uso funciona exatamente assim. À medida que altero a família ou o tamanho da fonte, a miniatura exibida é atualizada para sempre ter precisamente cinco linhas de texto de altura. A largura é dimensionada proporcionalmente para a imagem, a menos que seja maior que um determinado máximo (neste caso, bastante grande). Ao basear o tamanho da imagem na célula do caractere, ele funciona automaticamente em telas de alto DPI.

Embora o VT340 seja um objetivo nobre de emular, fixar a resolução da célula de caracteres em 10:20 (e, portanto, limitar a resolução para a tela inteira) é um erro. O VT340 foi apenas uma das várias implementações do sixel, portanto, o tamanho da fonte não é necessariamente mais correto.

Forçar 10:20 também levará a kludges feios. (Por exemplo, como responder a uma solicitação de tamanho da janela do terminal em pixels. Diga a verdade, presumindo que eles estarão posicionando janelas na tela? Ou, sempre retorne 800x480, presumindo que o usuário esteja dimensionando imagens para saída sixel? )

Estamos realmente falando sobre o terminal fingindo caracteres 10:20 para a imagem sixel?

sim.

um terminal moderno deve ser independente de fontes

Esta proposta é independente de fontes. O aplicativo não precisa saber nada sobre a fonte. Esse é o ponto.

Usando seqüências de escape, um programa executado pelo usuário pode determinar o tamanho da célula de caracteres em pixels e decidir como lidar de forma inteligente com a distorção para esse aplicativo.

Não sei exatamente qual método você está usando, mas a maneira como vi isso antes é com uma consulta XTerm proprietária para obter o tamanho do pixel da janela e outra consulta para obter o tamanho da célula da janela e, em seguida, usar isso dados para calcular o tamanho real do pixel da célula. As desvantagens de tal abordagem são:

  1. É proprietário, portanto, não funcionaria em um terminal real ou em qualquer emulador de terminal que corresponda exatamente a um terminal real.
  2. Se o usuário alterar o tamanho da fonte enquanto seu aplicativo estiver em execução, seus cálculos não estarão mais corretos e as imagens serão renderizadas no tamanho errado (a menos que você esteja recalculando continuamente o tamanho da fonte, o que parece impraticável).
  3. Se o usuário tiver uma tela de alta resolução e/ou tamanho de fonte grande, você será forçado a enviar uma imagem enorme para tentar corresponder a essa resolução. Considerando o quão ineficiente o Sixel é para começar, isso pode significar muita largura de banda.

Dito isso, entendo que este é um modo que algumas pessoas podem querer usar, e acho que deveríamos pelo menos ter uma opção para apoiá-lo um dia (por razões discutidas acima, isso simplesmente não é possível no momento). Mas, na minha opinião, esta não é a melhor abordagem para Sixel.

Tenho mais de 300 VT340 em usinas nucleares que gostaria de eventualmente
substituir.

Existem pacotes de emulação de terminal comercial que poderíamos usar, mas acho que
todos, exceto um, foram EoL'd.

Substituímos alguns deles por PCs Linux rodando XTerm (ou menos
frequentemente, Win10 + Hummingbird + WSL rodando XTerm), porque tem um
implementação de seisel de código aberto decente e meio ruim, mas
implementação ReGIS de código aberto.

A probabilidade de escrevermos um novo software para esta
sistema que gera o fluxo de octeto sixel é NIL.

Se o seu objetivo é enviar gráficos por um fluxo de octetos embutido, não há
são outras opções. Mas se você quiser suportar gráficos sixel, você deve
suportam gráficos sixel de uma forma que é meio semelhante ao anterior
implementações. Isso, infelizmente, significa que você deve emular o
comportamento de sistemas exemplares (ou seja, VT240, VT241, VT330 e VT340
terminais) mesmo quando se trata de integrar gráficos com texto.

Este é um mock-up do tipo de coisa que estou falando. Seria muito
bom se qualquer nova implementação do Sixel mantiver a compatibilidade com o existente
implementações para que as imagens não saiam da borda da tela ou apenas
preencher metade da tela.

https://vimeo.com/user32814426/review/467991744/ac5892fa7e

um terminal moderno deve ser independente de fontes

Esta proposta é independente de fontes. O aplicativo não precisa saber nada sobre a fonte. Esse é o ponto.

Eu quis dizer que o _terminal_ deve ser independente de fonte em vez de impor 10:20 em cada fonte. O aplicativo deve ser capaz de saber o tamanho real da fonte, se desejar, pois é o aplicativo que conhece o domínio do que está tentando mostrar e pode descobrir a melhor maneira de apresentar texto e gráficos juntos.

Usando seqüências de escape, um programa executado pelo usuário pode determinar o tamanho da célula de caracteres em pixels e decidir como lidar de forma inteligente com a distorção para esse aplicativo.

Não sei exatamente qual método você está usando, mas a maneira como vi isso antes é com uma consulta XTerm proprietária para obter o tamanho do pixel da janela e outra consulta para obter o tamanho da célula da janela e, em seguida, usar isso dados para calcular o tamanho real do pixel da célula.

Sim, está certo. Há também uma consulta para obter diretamente o tamanho da célula do caractere, mas não acho que seja tão amplamente suportado quanto apenas obter o tamanho da tela e dividir por LINHAS e COLUNAS.

As desvantagens de tal abordagem são:

1. It's proprietary, so wouldn't work on a real terminal, or any terminal emulator that exactly matched a real terminal.

Isso não é uma desvantagem. Significa apenas que o programa tem que voltar a fazer o que teria feito de qualquer maneira: presumir $TERM=="VT340" significa que as células de caracteres são 10:20, "VT240" significa 10:10, "mskermit" significa 8:8, e assim por diante.

Além disso, não é uma sequência proprietária do xterm. Obter o tamanho da tela é chamado de sequência de escape "dtterm", mas na verdade foi implementado pela primeira vez no SunView (SunOS, 1986). Acredito que foi posteriormente documentado no PHIGS Programming Manual (1992). Tente enviar "\e[14t" para alguns emuladores de terminal e você verá que é amplamente implementado.

2. If the user changes their font size while your application is running, then your calculations will no longer be correct, and images will be rendered at the wrong size (unless you're continuously recalculating the font size which seems impractical).

Isso não é um problema. O programa simplesmente intercepta o SIGWINCH e só recalcula se a janela realmente mudou.

3. If the user has a high resolution display, and/or large font size, you're forced to send through a massive image to try and match that resolution. Considering how inefficient Sixel is to start with, that can amount to a lot of bandwidth.

Sim, sixel é extremamente ineficiente. Mas em computadores modernos, enviar imagens em tela cheia é bastante útil, mesmo por ssh. O Microsoft Terminal tem algum tipo de limitação de baudrate?

A propósito, acredito que o sixel tenha um modo "alto DPI", onde cada ponto é dobrado em largura e altura. Eu nunca o usei e acho que o xterm nem o implementa, mas talvez isso aliviasse as preocupações com a largura de banda.

Dito isso, entendo que este é um modo que algumas pessoas podem querer usar, e acho que deveríamos pelo menos ter uma opção para apoiá-lo um dia (por razões discutidas acima, isso simplesmente não é possível no momento).

Este "modo" é simplesmente ter caracteres e gráficos alinhados, assim como os vários terminais sixel históricos e os emuladores atuais. Admito que não entendo por que não é possível fazer o mesmo no Microsoft Terminal. Se você disser que esse 10:20 kludge é o melhor que pode ser feito, eu confiarei que você está correto e obrigado por fazê-lo. Uma imagem distorcida é muito melhor do que nada.

Usando seqüências de escape, um programa executado pelo usuário pode determinar o tamanho da célula de caracteres em pixels e decidir como lidar de forma inteligente com a distorção para esse aplicativo.

@hackerb9 , qual é a sequência de escape real para obter as dimensões da fonte?

As sequências XTerm relevantes podem ser encontradas aqui: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html -- procure XTWINOPS.

Além disso, no Unix, você normalmente pode obter o tamanho do pixel interno do terminal junto com o tamanho da célula usando o TIOCGWINSZ ioctl. Com o openssh, isso também funciona remotamente.

Assim como um ponto de dados, o branch sixel para libvte está seguindo a rota agnóstica de tamanho de célula que @hackerb9 está falando. Ele trata os dados sixel recebidos como "pixel perfeito" e redimensiona as imagens recebidas anteriormente em níveis de zoom e tamanhos de fonte para cobrir uma extensão de célula consistente. Quando mesclada, esta implementação estará disponível para uma grande parte dos emuladores de terminal Linux, incluindo o Terminal GNOME, o Terminal XFCE, o Terminator, etc. Superficialmente, isso parece ser interoperável com pelo menos XTerm e mlterm.

Como o libvte registra um tamanho de célula virtual por imagem, seria trivial fazer isso funcionar com um tamanho de célula virtual fixo de 10x20 também para interoperação. No entanto, precisaríamos de uma maneira para os programas comunicarem suas taxas esperadas de pixel:célula para o terminal (por exemplo, estendendo os parâmetros DCS). Isso pode ser muito útil em geral, já que também forneceria uma forma de controle de densidade de pixels em ambientes com largura de banda restrita, como você mencionou acima.

Além disso, no Unix, você normalmente pode obter o tamanho do pixel interno do terminal junto com o tamanho da célula usando o TIOCGWINSZ ioctl. Com o openssh, isso também funciona remotamente.

O console do Linux retorna sempre 0 ... eles devem corrigir isso, mas parece que não estão dispostos também :-/

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

zadjii-msft picture zadjii-msft  ·  3Comentários

mrmlnc picture mrmlnc  ·  3Comentários

TayYuanGeng picture TayYuanGeng  ·  3Comentários

ghost picture ghost  ·  3Comentários

ghvanderweg picture ghvanderweg  ·  3Comentários