Pergunta

Este é um tiro longo, mas alguém sabe de um algoritmo para estimar e largura do texto categorização (para uma fonte de largura variável) com base em seu conteúdo?

Por exemplo, eu gostaria de saber que iiiiiiii não é tão grande como abcdefgh , que por sua vez não é tão grande como WWWWWWWW , apesar de todas as três cordas são oito caracteres de comprimento.

Esta é realmente uma tentativa para construir alguns inteligência para um método de sequência de truncagem, que no momento em que é truncar correctamente um visualmente grande cadeia, mas também é desnecessariamente truncar uma cadeia visualmente estreita, porque ambas as cadeias contêm o mesmo número de caracteres. É provavelmente suficiente para o algoritmo para classificar a seqüência de entrada como estreitar , normais ou ampla e, em seguida, truncar conforme o caso.

Esta questão não é realmente específico do idioma, mas se houver um algoritmo então eu vou implementá-lo em Java. Isto é para uma aplicação web. Estou ciente de que existem respostas sobre SO que lidar com este problema usando JavaScript para obter a largura de um elemento div contendo, mas gostaria de saber se uma solução do lado do servidor é possível.

Foi útil?

Solução

estruturas

A maioria GUI fornecer alguma forma de métricas de texto calcular para fontes de dados dispositivos de saída.

Usando java.awt.FontMetrics, por exemplo, eu acredito que você pode fazer isso:

import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics; 

public int measureText(Graphics g, String text) {
   g.setFont(new Font("TimesRoman", Font.PLAIN, 12));
   FontMetrics metrics = g.getFontMetrics();

   return metrics.stringWidth(text);
}

Não testado, mas você começa a idéia.


Sob Net você pode usar o Graphics.MeasureString método. Em C #:

private void MeasureStringMin(PaintEventArgs e)
{

    // Set up string.
    string measureString = "Measure String";
    Font stringFont = new Font("Arial", 16);

    // Measure string.
    SizeF stringSize = new SizeF();
    stringSize = e.Graphics.MeasureString(measureString, stringFont);

    // Draw rectangle representing size of string.
    e.Graphics.DrawRectangle(new Pen(Color.Red, 1), 0.0F, 0.0F, stringSize.Width, stringSize.Height);

    // Draw string to screen.
    e.Graphics.DrawString(measureString, stringFont, Brushes.Black, new PointF(0, 0));
}

Outras dicas

Isso funcionou para mim:

AffineTransform af = new AffineTransform();     
FontRenderContext fr = new FontRenderContext(af,true,true);     
Font f = new Font("Arial", 0, 10); // use exact font
double width= f.getStringBounds("my string", fr).getWidth();      

Para uma aplicação web, você pode não (realmente) obter uma estimativa adequada. Fontes diferentes têm diferentes larguras, de modo que este não só depende do cliente (browser) e seu zoom e configurações de DPI, mas também sobre as fontes apresentar nessa máquina (e sistema operacional) ou suas substituições.

Se você necessidade exata medição, criar um gráfico (bitmap, SVG, ou mesmo algum PDF ou qualquer outro) que será layouted e processado no servidor e não no cliente.

Não há uma solução do lado do servidor confiável para calcular a largura do texto. (fora de criar uma imagem do texto e, provavelmente, SVG)

Se você tentar uma ferramenta para fora como navegador-shots e executá-lo contra páginas relativamente básicos, você vai imediatamente Veja porque. É difícil prever como ampla até mesmo os exemplos mais mundanos vai sair, muito menos se um usuário decide zoom no navegador etc ...

Não é indicado precisamente você pode querer truncar a string (que poderia ser útil para dar soluções potenciais), mas um comum é porque você quer cortar o texto em algum momento e proporcionar uma elipse.

Isso pode ser feito de forma confiável em muitas plataformas navegador usando uma propriedade css, e NÃO javascript:

http://www.jide.fr/emulate -text-overflowellipsis-em-firefox-com-css

Você realmente não têm nenhuma maneira de saber o navegador, as configurações de fonte, tamanho da tela etc o cliente está usando. (OK, às vezes os cabeçalhos de solicitação fornecer uma indicação, mas realmente nada consistente ou confiável.)

Então, eu faria:

  • exibir algum texto de exemplo no Internet Explorer com as configurações padrão em um tamanho de tela / janela de 1024x768 (este é geralmente o tamanho mais comum)
  • fazer um caracteres / linha média com esta configuração e uso que para a sua estimativa.

Eu geralmente encontrados este "bom o suficiente", por exemplo, para estimar o número de linhas que algum texto vai ocupar em um navegador, a fim de estimar quantos anúncios para mostrar ao lado do texto.

Se foi realmente muito crucial para você, então eu posso imaginar um esquema complicado pelo qual você inicialmente enviar algum Javascript para o cliente, que então toma uma medida e envia de volta para o servidor, e você, em seguida, usar essa informação para o futuro páginas para esse cliente. Eu não posso imaginar que é geralmente vale a pena o esforço, no entanto.

Eu acho que você deve escolher uma das seguintes soluções:

  • Exact solução: Soma-se a largura para cada caractere na seqüência (a maioria das APIs vai lhe dar esta informação)
  • Breve estimativa:. Assumir a largura máximo ou mínimo e multiplicá-lo com o número de caracteres

É claro que alguns estimam mista é possível, mas acho que isso é muito esforço na direção errada.

Para uma agradável * A solução do lado do cliente, você pode tentar uma abordagem híbrida CSS-and-Javascript como sugerido por a resposta de RichieHindle à minha pergunta .

Uma vez que você não sabe qual fonte o usuário verá a página no (eles sempre pode substituir a seleção, Ctrl + página, etc), o lugar "certo" de fazer isso é no navegador .. . embora os navegadores não se torna mais fácil!

* quando eu digo "bom", quero dizer "provavelmente bom, mas eu realmente não tenho tentado ainda".

Esta é realmente uma tentativa de construir alguns smarts em um método corda truncamento [...]

Será que realmente vale o esforço? Tivemos este problema exato. E isso foi em todos os idiomas. A correção foi para deixá-lo como está. A complexidade de manter essa inteligência se aumenta rapidamente (e provavelmente exponencialmente) com cada idioma que você adicionar suporte para. Daí a nossa decisão.

[...] um algoritmo para estimar e largura do texto categorização (para uma fonte de largura variável) com base em seu conteúdo?

A maioria das fontes-bibliotecas vai lhe dar esta informação. Mas isso é muito coisas de baixo nível. A idéia básica é a de passar uma cadeia e voltar a largura em pontos.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top