2010-11-11 5 views
12

J'utilise GDI + pour dessiner une chaîne sur un objet Graphics.Remplir du texte à l'intérieur du rectangle

Je veux la chaîne pour tenir dans un rectangle prédéfini (sans casser les lignes)

Est-ce qu'il ya de toute façon de faire cela en plus d'utiliser TextRenderer.MeasureString() dans une boucle jusqu'à ce que la taille souhaitable est de retour?

quelque chose comme:

DrawScaledString(Graphics g, string myString, Rectangle rect) 
+0

Vous pouvez appliquer une transformation matricielle, mais cela fait des années que je n'y ai pas touché. – leppie

+0

N'est-ce pas un peu de frais généraux? – Nissim

Répondre

8

Vous pouvez utiliser le ScaleTransform

string testString = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
Suspendisse et nisl adipiscing nisl adipiscing ultricies in ac lacus. 
Vivamus malesuada eros at est egestas varius tincidunt libero porttitor. 
Pellentesque sollicitudin egestas augue, ac commodo felis ultricies sit amet."; 

Bitmap bmp = new Bitmap(300, 300); 
using (var graphics = Graphics.FromImage(bmp)) 
{ 
    graphics.FillRectangle(Brushes.White, graphics.ClipBounds); 
    var stringSize = graphics.MeasureString(testString, this.Font); 
    var scale = bmp.Width/stringSize.Width; 
    if (scale < 1) 
    { 
     graphics.ScaleTransform(scale, scale); 
    } 
    graphics.DrawString(testString, this.Font, Brushes.Black, new PointF()); 
} 
bmp.Save("lorem.png", System.Drawing.Imaging.ImageFormat.Png); 

Mais vous pourriez obtenir des effets d'alias.

alt text

Edit:

Mais si vous voulez changer la taille de la police à la place, je suppose que vous pouvez changer la taille des caractères avec scale dans le code ci-dessus au lieu d'utiliser à transformer l'échelle. Essayez les deux et comparez la qualité du résultat.

+0

Merci l'homme ... J'ai changé la taille de la police en fonction de l'échelle, fait de petits ajustements et cela a bien fonctionné ... – Nissim

5

Voici une autre solution au problème, il est un peu intensive car elle nécessite un peu juste de la création et la destruction police, mais peut mieux fonctionner, en fonction de votre situation et les besoins:

public class RenderInBox 
{ 
    Rectangle box; 
    Form root; 
    Font font; 
    string text; 

    StringFormat format; 

    public RenderInBox(Rectangle box, Form root, string text, string fontFamily, int startFontSize = 150) 
    { 
     this.root = root; 
     this.box = box; 
     this.text = text; 

     Graphics graphics = root.CreateGraphics(); 

     bool fits = false; 
     int size = startFontSize; 
     do 
     { 
      if (font != null) 
       font.Dispose(); 

      font = new Font(fontFamily, size, FontStyle.Regular, GraphicsUnit.Pixel); 

      SizeF stringSize = graphics.MeasureString(text, font, box.Width, format); 

      fits = (stringSize.Height < box.Height); 
      size -= 2; 
     } while (!fits); 

     graphics.Dispose(); 

     format = new StringFormat() 
     { 
      Alignment = StringAlignment.Center, 
      LineAlignment = StringAlignment.Center 
     }; 

    } 

    public void Render(Graphics graphics, Brush brush) 
    { 
     graphics.DrawString(text, font, brush, box, format); 
    } 
} 

Pour l'utiliser simplement créer une nouvelle classe et appeler Render(). Notez que ceci est spécifiquement écrit pour le rendu à un formulaire.

var titleBox = new RenderInBox(new Rectangle(10, 10, 400, 100), thisForm, "This is my text it may be quite long", "Tahoma", 200); 
titleBox.Render(myGraphics, Brushes.White); 

Vous devez créer l'objet RenderInBox dès le départ en raison de sa nature de création intensive. Par conséquent, il ne convient pas à tous les besoins.

+0

Excellent, exactement ce dont j'avais besoin! – Gromer

Questions connexes