2010-11-11 79 views
12

Sto usando GDI + per disegnare una stringa su un oggetto Graphics.Riempimento del testo all'interno del rettangolo

voglio la stringa per adattarsi all'interno di un rettangolo predefinito (senza rompere tutte le righe)

è che c'è in ogni caso di fare questo oltre ad utilizzare TextRenderer.MeasureString() in un ciclo finché non viene restituita la dimensione desiderabile?

qualcosa di simile:

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

È possibile applicare una trasformazione matrix, ma sono passati anni dall'ultima volta che l'ho toccato. – leppie

+0

Non è un po 'sovraccarico? – Nissim

risposta

8

È possibile utilizzare lo 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); 

Ma si potrebbe ottenere alcuni effetti alias.

alt text

Edit:

Ma se si desidera modificare la dimensione del carattere, invece Credo che si può modificare la dimensione del carattere con scale nel codice qui sopra invece di utilizzare la scala di trasformare. Prova entrambi e confronta la qualità del risultato.

+0

Grazie amico ... Ho cambiato la dimensione del carattere in base alla scala, apportato piccole regolazioni e ha funzionato benissimo ... – Nissim

5

Ecco un'altra soluzione al problema, è un po 'intensa in quanto richiede un bel po' di creazione del carattere e della distruzione, ma può funzionare meglio, a seconda delle circostanze e le esigenze:

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

Per utilizzarlo è sufficiente crea una nuova classe e chiama Render(). Nota questo è specificamente scritto per il rendering in un modulo.

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

È necessario creare l'oggetto in anticipo RenderInBox grazie alla sua intensa la natura della creazione. Pertanto non è adatto ad ogni esigenza.

+0

Eccellente, esattamente quello di cui avevo bisogno! – Gromer