29 votes

Silverlight: Largeur des glyphes

Scénario

Je veux utiliser Glyphs sur WP7 pour créer une ligne de texte qui est justifiée, c'est-à-dire qui touche les bordures gauche et droite du rectangle environnant.

Ma solution

 var glyphs = new Glyphs();
glyphs.FontUri = new Uri("/MyAssembly;component/MyPath/MyFont.ttf", UriKind.Relative);
glyphs.FontRenderingEmSize = 20;
glyphs.Fill = new SolidColorBrush(Colors.Red);

// measue width of space
glyphs.UnicodeString = " ";
glyphs.Measure(availableSize);
double spaceWidth = glyphs.DesiredSize.Width;
glyphs.InvalidateMeasure();

// setup justified text
string text = "Lorem Ipsum is dummy text of the printing and typesetting industry.";
int spaceCount = 10; // number of spaces in above text

glyphs.UnicodeString = text;
glyphs.Measure(availableSize); // now DesiredSize.Width = width of left aligned text

// I suspect my error to be in this formula:
double spaceAdvance = ((availableSize.Width - glyphs.DesiredSize.Width) 
                       / spaceCount + spaceWidth) / glyphs.FontRenderingEmSize * 100;
string spaceAdvanceString = String.Format(",{0};", spaceAdvance);

var indices = new StringBuilder();
foreach (char c in text)
{
    if (c == ' ')   indices.Append(spaceAdvanceString);
    else            indices.Append(';');
}
glyphs.Indices = indices.ToString();
 

Problème et question

Le côté droit des glyphes ne touche pas exactement la frontière availableSize.Width mais est à quelques pixels, et cela semble bizarre quand il y a plusieurs lignes de texte empilées.

Quel est le problème avec mon calcul?

2voto

Chris Bednarski Points 2264

Ce peut-être des problèmes avec virgule flottante de précision.

En règle générale, chaque virgule flottante opération arithmétique introduit une erreur au moins égale à la machine de précision (c'est à dire le plus petit nombre qui, ajouté à l'1.0, produit un résultat à virgule flottante qui est différent de 1.0) dans le résultat. Cette erreur est connue comme l'erreur d'arrondi. Les erreurs d'arrondi sont cumulatifs et, parfois, dépend de l'ordre des opérations.

Au lieu de

double spaceAdvance = ((availableSize.Width - glyphs.DesiredSize.Width)
         / spaceCount + spaceWidth) / glyphs.FontRenderingEmSize * 100;

essayez de déplacer la multiplication à l'avant, c'est à dire

double spaceAdvance = 100.0 * ((availableSize.Width - glyphs.DesiredSize.Width)
         / spaceCount + spaceWidth) / glyphs.FontRenderingEmSize;

Alternativement, vous pouvez également essayer

double spaceAdvance = (100.0 * (availableSize.Width - glyphs.DesiredSize.Width)
         / spaceCount + 100.0 * spaceWidth) / glyphs.FontRenderingEmSize;

1voto

Chris Bednarski Points 2264

Quel sujet de la disposition de l'arrondissement?

var glyphs = new Glyphs();
glyphs.FontUri = new Uri("/MyAssembly;component/MyPath/MyFont.ttf", UriKind.Relative);
glyphs.FontRenderingEmSize = 20;
glyphs.Fill = new SolidColorBrush(Colors.Red);
glyphs.UseLayoutRounding = false;

Aussi, vous voudrez peut-être essayer avec ActualWidth au lieu de DesiredSize.Largeur

double spaceAdvance = ((availableSize.Width - glyphs.ActualWidth) / 
             spaceCount + spaceWidth) / glyphs.FontRenderingEmSize * 100.0;

1voto

Jasper Points 360

Proposition alternative: vous pouvez utiliser le contrôle RichTextBox qui prend en charge "justifier".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X