Question

C’est un long plan, mais est-ce que quelqu'un connaît un algorithme permettant d’estimer et de catégoriser la largeur du texte (pour une police à largeur variable) en fonction de son contenu?

Par exemple, j'aimerais savoir que iiiiiiii n'est pas aussi large que abcdefgh , ce qui n'est pas aussi large que WWWWWWWW , même si les trois chaînes ont une longueur de huit caractères.

Il s’agit en fait d’une tentative de construction de systèmes intelligents dans une méthode de troncature de chaîne, qui tronque actuellement correctement une chaîne visuellement large, mais tronque également inutilement une chaîne visuellement étroite, car les deux chaînes contiennent le même nombre de caractères. Il suffit probablement que l'algorithme classe la chaîne d'entrée dans les catégories étroit , normal ou large , puis tronque le cas échéant.

Cette question n'est pas vraiment spécifique à la langue, mais s'il y a un algorithme, je l'implémenterai en Java. Ceci est pour une application web. Je suis conscient qu'il existe des réponses sur SO qui traitent de ce problème en utilisant JavaScript pour obtenir la largeur d'un élément div contenant, mais je me demandais si une solution côté serveur était possible.

Était-ce utile?

La solution

La plupart des frameworks d'interface graphique fournissent un moyen de calculer les métriques de texte des polices sur des périphériques de sortie donnés.

Utilisation de java.awt.FontMetrics , par exemple, je pense que vous pouvez le faire:

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);
}

Non testé, mais vous voyez l'idée.

Sous .Net, vous pouvez utiliser le Graphics Méthode .MeasureString . En 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));
}

Autres conseils

Cela a fonctionné pour moi:

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();      

Pour une application Web, vous ne pouvez pas (vraiment) obtenir une estimation correcte. Les différentes polices ont des largeurs différentes, de sorte que cela dépend non seulement du client (navigateur) et de ses paramètres de zoom et DPI, mais également des polices présentes sur cette machine (et son système d'exploitation) ou de leurs substitutions.

Si vous avez besoin de mesures exactes, créez un graphique (bitmap, SVG ou même un fichier PDF ou autre) qui sera mis en forme et rendu sur le serveur et non sur le client.

Il n'existe pas de solution côté serveur fiable pour calculer la largeur du texte. (en dehors de la création d'une image du texte et probablement du format SVG)

Si vous essayez un outil du type avec des clichés de navigateur et que vous l'exécutez sur des pages relativement simples, vous obtiendrez immédiatement voir pourquoi. Il est difficile de prévoir l'étendue même des exemples les plus banals, et encore moins si un utilisateur décide de zoomer dans le navigateur, etc.

Il n'est pas précisé que vous souhaitiez tronquer la chaîne (cela peut être utile pour donner des solutions potentielles), mais une solution courante est que vous souhaitez couper le texte à un moment donné et fournir une ellipse.

Cela peut être effectué de manière fiable sur de nombreuses plateformes de navigateur en utilisant une propriété css et NON javascript:

http://www.jide.fr/emulate -text-overflowellipsis-in-firefox-with-css

Vous n'avez vraiment aucun moyen de savoir quel navigateur, quels paramètres de police, quelle taille d'écran, etc. le client utilise. (OK, parfois, les en-têtes de requête fournissent une indication, mais rien n’est vraiment cohérent ou fiable.)

Je voudrais donc:

  • affiche un exemple de texte dans Internet Explorer avec les paramètres par défaut pour une taille d’écran / fenêtre de 1024x768 (il s’agit généralement de la taille la plus courante)
  • prenez une moyenne caractères / ligne avec cette configuration et utilisez-la pour votre estimation.

En général, j’ai trouvé cet "assez bon", par exemple, pour estimer le nombre de lignes qu'un texte utilisera dans un navigateur, afin d'estimer le nombre d'annonces à afficher à côté du texte.

Si cela était vraiment crucial pour vous, alors je peux imaginer un schéma compliqué dans lequel vous envoyez initialement du Javascript au client, qui prend ensuite une mesure et le renvoie à votre serveur, et vous utilisez ensuite ces informations pour l'avenir pages pour ce client. Je ne peux pas imaginer que cela en vaut généralement la peine.

Je pense que vous devriez choisir l'une de ces solutions:

  • Solution exacte: additionnez la largeur de chaque caractère de la chaîne (la plupart des API vous donneront cette information)
  • Estimation rapide: prenez la largeur maximale ou minimale et multipliez-la par le nombre de caractères.

Bien sûr, une estimation mixte est possible, mais je pense que c’est trop d’effort dans la mauvaise direction.

Pour une bonne * solution côté client, vous pouvez essayer une approche hybride CSS-et-Javascript comme suggéré par Réponse de RichieHindle à ma question .

Etant donné que vous ne savez pas dans quelle police l'utilisateur verra la page (ils peuvent toujours remplacer votre sélection, Ctrl + la page, etc.), le "droit" l’endroit pour le faire est sur le navigateur ... bien que les navigateurs ne le rendent pas facile!

* lorsque je dis "bien", je veux dire "probablement bien, mais je ne l'ai pas encore essayé".

  

Il s’agit en fait d’une tentative de construire des intelligents dans une méthode de troncature de chaîne [...]

Cela en vaut-il vraiment la peine? Nous avons eu ce problème exact. Et c'était à travers les langues. Le correctif était de le laisser tel quel. Maintenir cette intelligence de plus en plus complexe augmente rapidement (et probablement de façon exponentielle) avec chaque langue que vous ajoutez. D'où notre décision.

  

[...] un algorithme d'estimation et de catégorisation de la largeur du texte (pour une police à largeur variable) en fonction de son contenu?

La plupart des bibliothèques de polices vous donneront ces informations. Mais ce sont des trucs assez bas. L'idée de base est de passer une chaîne et de récupérer la largeur en points.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top