Centrer la sortie de texte à partir de Graphics.DrawSsortingng ()

J’utilise la classe Graphics .NETCF (Windows Mobile) et la méthode DrawSsortingng() pour rendre un seul caractère à l’écran.

Le problème est que je n’arrive pas à le centrer correctement. Peu importe ce que je définis pour la coordonnée Y de l’emplacement du rendu de la chaîne, celle-ci est toujours inférieure à cette valeur et plus la taille du texte est grande, plus le décalage Y est élevé.

Par exemple, à la taille de texte 12, le décalage est d’environ 4, mais à 32 le décalage est d’environ 10.

Je veux que le personnage occupe verticalement la majeure partie du rectangle dans lequel il est dessiné et soit centré horizontalement. Voici mon code de base. this fait référence au contrôle utilisateur dans lequel il est dessiné.

 Graphics g = this.CreateGraphics(); float padx = ((float)this.Size.Width) * (0.05F); float pady = ((float)this.Size.Height) * (0.05F); float width = ((float)this.Size.Width) - 2 * padx; float height = ((float)this.Size.Height) - 2 * pady; float emSize = height; g.DrawSsortingng(letter, new Font(FontFamily.GenericSansSerif, emSize, FontStyle.Regular), new SolidBrush(Color.Black), padx, pady); 

Oui, je sais qu’il existe un contrôle d’étiquette que je pourrais utiliser à la place et définir le centrage avec cela, mais je dois en fait le faire manuellement avec la classe Graphics .

Je voudrais append un autre vote pour l’object SsortingngFormat. Vous pouvez l’utiliser simplement pour spécifier “centre, centre” et le texte sera dessiné centralement dans le rectangle ou les points fournis:

 SsortingngFormat format = new SsortingngFormat(); format.LineAlignment = SsortingngAlignment.Center; format.Alignment = SsortingngAlignment.Center; 

Cependant, il y a un problème avec CF. Si vous utilisez Center pour les deux valeurs, cela désactive TextWrapping. Aucune idée de ce qui se passe, cela semble être un bug avec les FC.

Pour aligner un texte, utilisez ce qui suit:

 SsortingngFormat sf = new SsortingngFormat(); sf.LineAlignment = SsortingngAlignment.Center; sf.Alignment = SsortingngAlignment.Center; e.Graphics.DrawSsortingng("My Ssortingng", this.Font, Brushes.Black, ClientRectangle, sf); 

Veuillez noter que le texte ici est aligné dans les limites données. Dans cet exemple, il s’agit du ClientRectangle.

Grâce à une combinaison de suggestions, je suis arrivé à ceci:

  private void DrawLetter() { Graphics g = this.CreateGraphics(); float width = ((float)this.ClientRectangle.Width); float height = ((float)this.ClientRectangle.Width); float emSize = height; Font font = new Font(FontFamily.GenericSansSerif, emSize, FontStyle.Regular); font = FindBestFitFont(g, letter.ToSsortingng(), font, this.ClientRectangle.Size); SizeF size = g.MeasureSsortingng(letter.ToSsortingng(), font); g.DrawSsortingng(letter, font, new SolidBrush(Color.Black), (width-size.Width)/2, 0); } private Font FindBestFitFont(Graphics g, Ssortingng text, Font font, Size proposedSize) { // Compute actual size, shrink if needed while (true) { SizeF size = g.MeasureSsortingng(text, font); // It fits, back out if (size.Height <= proposedSize.Height && size.Width <= proposedSize.Width) { return font; } // Try a smaller font (90% of old size) Font oldFont = font; font = new Font(font.Name, (float)(font.Size * .9), font.Style); oldFont.Dispose(); } } 

Jusqu'à présent, cela fonctionne parfaitement.

La seule chose que je voudrais changer est de déplacer l'appel FindBestFitFont () à l'événement OnResize () pour que je ne l'appelle pas chaque fois que je dessine une lettre. Il suffit de l'appeler lorsque la taille du contrôle change. Je viens de l'inclure dans la fonction pour l'exhaustivité.

Pour dessiner un texte centré:

 TextRenderer.DrawText(g, "my text", Font, Bounds, ForeColor, BackColor, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.GlyphOverhangPadding); 

La détermination de la taille de police optimale pour remplir une zone est un peu plus difficile. Une solution de travail que j’ai trouvée est une version d’essai: commencez par une grande police, puis mesurez la chaîne à plusieurs resockets et réduisez la police jusqu’à ce qu’elle soit ajustée.

 Font FindBestFitFont(Graphics g, Ssortingng text, Font font, Size proposedSize, TextFormatFlags flags) { // Compute actual size, shrink if needed while (true) { Size size = TextRenderer.MeasureText(g, text, font, proposedSize, flags); // It fits, back out if ( size.Height <= proposedSize.Height && size.Width <= proposedSize.Width) { return font; } // Try a smaller font (90% of old size) Font oldFont = font; font = new Font(font.FontFamily, (float)(font.Size * .9)); oldFont.Dispose(); } } 

Vous utiliseriez ceci comme:

 Font bestFitFont = FindBestFitFont(g, text, someBigFont, sizeToFitIn, flags); // Then do your drawing using the bestFitFont // Don't forget to dispose the font (if/when needed) 

Vous pouvez utiliser une instance de l’object SsortingngFormat transmise à la méthode DrawSsortingng pour centrer le texte.

Voir la méthode Graphics.DrawSsortingng et la classe SsortingngFormat .

Voici un code. Cela suppose que vous le faites sur un formulaire ou un UserControl.

 Graphics g = this.CreateGraphics(); SizeF size = g.MeasureSsortingng("ssortingng to measure"); int nLeft = Convert.ToInt32((this.ClientRectangle.Width / 2) - (size.Width / 2)); int nTop = Convert.ToInt32((this.ClientRectangle.Height / 2) - (size.Height / 2)); 

De votre message, il semble que la partie ClientRectangle (comme dans, vous ne l’utilisez pas) vous pose problème.