2010-11-11 22 views
12

Estoy usando GDI + para dibujar una cadena en un objeto Graphics.Rellenar texto dentro del rectángulo

Quiero la cadena que encaja dentro de un rectángulo predefinido (sin romper ninguna línea)

es que hay modos de hacer esto, además de utilizar TextRenderer.MeasureString() en un bucle hasta que se devuelva el tamaño deseable?

algo como:

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

Puede aplicar una transformación matricial, pero han pasado años desde la última vez que lo toqué. – leppie

+0

¿No es un poco caro? – Nissim

Respuesta

8

Puede utilizar el 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); 

Pero es posible obtener algunos efectos de alias.

alt text

Editar:

Pero si desea cambiar el tamaño de fuente en vez supongo que se puede cambiar el tamaño de la fuente con scale en el código anterior en lugar de utilizar la transformada de escala. Pruebe ambos y compare la calidad del resultado.

+0

Gracias hombre ... Cambié el tamaño de fuente de acuerdo con la escala, hice pequeños ajustes y funcionó muy bien ... – Nissim

5

Aquí hay otra solución al problema, que es un poco intenso, ya que requiere un poco de creación de la fuente y la destrucción, pero puede funcionar mejor, en función de sus circunstancias y necesidades:

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

Para usarlo, simplemente crea una nueva clase y llama a Render(). Tenga en cuenta que esto está escrito específicamente para representar en un formulario.

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

Debe crear el objeto RenderInBox por adelantado debido a su naturaleza de creación intensiva. Por lo tanto, no es adecuado para todas las necesidades.

+0

Excelente, ¡exactamente lo que necesitaba! – Gromer

Cuestiones relacionadas